Skip to content

Commit

Permalink
Replaced creating of the dynamic Ivy repository with absolute paths i…
Browse files Browse the repository at this point in the history
…n the patterns with LocalIvyArtifactPathComponentMetadataRule, which fixes artifact paths on the fly because we have to support RepositoriesMode.FAIL_ON_PROJECT_REPOS https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin.html#configuration.dependencyResolutionManagement
  • Loading branch information
AlexanderBartash committed Oct 13, 2024
1 parent eb773d4 commit a4e556c
Show file tree
Hide file tree
Showing 21 changed files with 468 additions and 548 deletions.
7 changes: 3 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@
### Changed

- Move `localPlatformArtifacts()` to the top of the `defaultRepositories()` list
- Improved build performance by pre-creating Ivy XML files in the extracted IDE location.
- Improved build performance by making the local Ivy repository first in the list and making it an exclusive Gradle repository.
- Improved build performance by making the local Ivy repository an exclusive Gradle repository.

### Fixed

- Fixed issue #1778 by removing a hash of the absolute artifact path appended to the end of the version string. That hash made artifact version different on different PCs and also breaks Gradle dependency locking.
- Fixed issue #1778 by removing a hash of the absolute artifact path appended to the end of the version string. That hash made the versions different on different PCs and also breaks Gradle dependency locking.
- Add the missing `org.jetbrains.kotlin.platform.type=jvm` attribute to the `intellijPlatformRuntimeClasspath` configuration manually as it's not inherited from the `runtimeClasspath`.
- Fixed `Could not generate a decorated class for type PluginArtifactRepository.` when creating a custom plugin repository.
- #1779 Fixes compatibility with Gradle dependency verification. Previously it was failing with "Failed to create MD5 hash for file".
- Fixed issue #1779 about compatibility with Gradle dependency verification. Previously it was failing with "Failed to create MD5 hash for file".

## [2.1.0]

Expand Down
20 changes: 20 additions & 0 deletions api/IntelliJPlatformGradlePlugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,20 @@ public final class org/jetbrains/intellij/platform/gradle/Constants$Plugins$Exte
public static final field KOTLIN Ljava/lang/String;
}

public final class org/jetbrains/intellij/platform/gradle/Constants$Repositories {
public static final field ANDROID_STUDIO_INSTALLERS Ljava/lang/String;
public static final field INSTANCE Lorg/jetbrains/intellij/platform/gradle/Constants$Repositories;
public static final field INTELLI_J_PLATFORM_CUSTOM_PLUGIN Ljava/lang/String;
public static final field INTELLI_J_PLATFORM_DEPENDENCIES Ljava/lang/String;
public static final field INTELLI_J_REPOSITORY_NIGHTLY Ljava/lang/String;
public static final field INTELLI_J_REPOSITORY_RELEASES Ljava/lang/String;
public static final field INTELLI_J_REPOSITORY_SNAPSHOTS Ljava/lang/String;
public static final field JET_BRAINS_IDE_INSTALLERS Ljava/lang/String;
public static final field JET_BRAINS_MARKETPLACE Ljava/lang/String;
public static final field JET_BRAINS_RUNTIME Ljava/lang/String;
public static final field LOCAL_INTELLI_J_PLATFORM_ARTIFACTS Ljava/lang/String;
}

public final class org/jetbrains/intellij/platform/gradle/Constants$Sandbox {
public static final field CONFIG Ljava/lang/String;
public static final field CONTAINER Ljava/lang/String;
Expand Down Expand Up @@ -447,6 +461,12 @@ public abstract class org/jetbrains/intellij/platform/gradle/artifacts/transform
public final class org/jetbrains/intellij/platform/gradle/artifacts/transform/ExtractorTransformer$Companion {
}

public abstract class org/jetbrains/intellij/platform/gradle/artifacts/transform/LocalIvyArtifactPathComponentMetadataRule : org/gradle/api/artifacts/ComponentMetadataRule {
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun execute (Ljava/lang/Object;)V
public fun execute (Lorg/gradle/api/artifacts/ComponentMetadataContext;)V
}

public abstract class org/jetbrains/intellij/platform/gradle/artifacts/transform/LocalPluginsNormalizationTransformers : org/gradle/api/artifacts/transform/TransformAction {
public static final field Companion Lorg/jetbrains/intellij/platform/gradle/artifacts/transform/LocalPluginsNormalizationTransformers$Companion;
public fun <init> (Lorg/gradle/api/file/FileSystemOperations;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package org.jetbrains.intellij.platform.gradle
import org.jetbrains.intellij.platform.gradle.Constants.Tasks
import kotlin.io.path.fileSize
import kotlin.io.path.readText
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertTrue

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package org.jetbrains.intellij.platform.gradle

import org.jetbrains.intellij.platform.gradle.Constants.Tasks
import kotlin.io.path.readText
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertTrue

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ kotlin {
jvmToolchain(17)
}

// Ignore configurations containing dependencies pointing to a directory, because when used with Grale's dependency
// verification (pgp option) it fails to create a hash for the directories, with a very obscure error:
// Ivalid UTF-8 input
configurations {
named("jetbrainsRuntimeLocalInstance") {
resolutionStrategy.disableDependencyVerification()
}
named("jetbrainsRuntimeDependency") {
resolutionStrategy.disableDependencyVerification()
}
named("jetbrainsRuntime") {
resolutionStrategy.disableDependencyVerification()
}
}

buildscript {
// https://docs.gradle.org/current/userguide/dependency_locking.html
dependencyLocking {
Expand All @@ -37,14 +52,15 @@ repositories {
mavenCentral()

intellijPlatform {
//jetbrainsRuntime()
defaultRepositories()
}
}

dependencies {
intellijPlatform {
create(intellijPlatformTypeProperty, intellijPlatformVersionProperty)
instrumentationTools()
//instrumentationTools()
testFramework(TestFrameworkType.Platform)

// This is important for bug reproduction because we need some dependencies in the test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,13 @@
<key-server uri="https://keyoxide.org/"/>
<key-server uri="https://keys.openpgp.org/"/>
</key-servers>
<trusted-artifacts>
<!--<trust group="bundledModule" reason="Testing"/>-->
<!--<trust group="bundledPlugin" reason="Testing"/>-->
<!--<trust group="localIde" reason="Testing"/>-->
<!--<trust group="localPlugin" reason="Testing"/>-->
<!--<trust group="localJetBrainsRuntime" reason="Testing"/>-->
<!--<trust group="com.jetbrains" name="jbr" reason="Testing"/>-->
</trusted-artifacts>
</configuration>
</verification-metadata>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ kotlin {
jvmToolchain(17)
}

// Ignore configurations containing dependencies pointing to a directory, because when used with Grale's dependency
// verification (pgp option) it fails to create a hash for the directories, with a very obscure error:
// Ivalid UTF-8 input
configurations {
named("jetbrainsRuntimeLocalInstance") {
resolutionStrategy.disableDependencyVerification()
}
named("jetbrainsRuntimeDependency") {
resolutionStrategy.disableDependencyVerification()
}
named("jetbrainsRuntime") {
resolutionStrategy.disableDependencyVerification()
}
}

buildscript {
// https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1778
// https://docs.gradle.org/current/userguide/dependency_locking.html
Expand All @@ -39,14 +54,15 @@ repositories {
mavenCentral()

intellijPlatform {
//jetbrainsRuntime()
defaultRepositories()
}
}

dependencies {
intellijPlatform {
create(intellijPlatformTypeProperty, intellijPlatformVersionProperty)
instrumentationTools()
//instrumentationTools()
testFramework(TestFrameworkType.Platform)

// This is important for bug reproduction because we need some dependencies in the test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,34 @@ kotlin {
jvmToolchain(17)
}

// Ignore configurations containing dependencies pointing to a directory, because when used with Grale's dependency
// verification (pgp option) it fails to create a hash for the directories, with a very obscure error:
// Ivalid UTF-8 input
configurations {
named("jetbrainsRuntimeLocalInstance") {
resolutionStrategy.disableDependencyVerification()
}
named("jetbrainsRuntimeDependency") {
resolutionStrategy.disableDependencyVerification()
}
named("jetbrainsRuntime") {
resolutionStrategy.disableDependencyVerification()
}
}

repositories {
mavenCentral()

intellijPlatform {
//jetbrainsRuntime()
defaultRepositories()
}
}

dependencies {
intellijPlatform {
create(intellijPlatformTypeProperty, intellijPlatformVersionProperty)
instrumentationTools()
//instrumentationTools()
testFramework(TestFrameworkType.Platform)

// This is important for bug reproduction because we need some dependencies in the test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<trusted-artifacts>
<trust group="bundledModule" reason="Testing"/>
<trust group="bundledPlugin" reason="Testing"/>
<trust group="localIde" reason="Testing"/>
<trust group="localPlugin" reason="Testing"/>
<trust group="localJetBrainsRuntime" reason="Testing"/>
<trust group="com.jetbrains" name="jbr" reason="Testing"/>
</trusted-artifacts>
</configuration>
</verification-metadata>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import org.jetbrains.intellij.platform.gradle.utils.toVersion

object Constants {
const val CACHE_DIRECTORY = ".intellijPlatform"
const val IVY_FILES_DIRECTORY = "localPlatformArtifacts"

object Plugin {
const val ID = "org.jetbrains.intellij.platform"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import kotlin.io.path.listDirectoryEntries

/**
* The artifact transformer collecting JAR files located within the IntelliJ Platform or plugin archives.
* @see org.jetbrains.intellij.platform.gradle.artifacts.transform.LocalIvyArtifactPathComponentMetadataRule
*/
@DisableCachingByDefault(because = "Not worth caching")
abstract class CollectorTransformer : TransformAction<CollectorTransformer.Parameters> {
Expand Down Expand Up @@ -91,7 +92,7 @@ abstract class CollectorTransformer : TransformAction<CollectorTransformer.Param
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#non-bundled-plugin
// For other plugins, we never (usually?) get into this block, because their Ivy artifacts already
// list jars, instead of pointing to a directory, see:
// See also org.jetbrains.intellij.platform.gradle.models.IvyModuleKt.explodeIntoIvyJarsArtifactsRelativeTo
// org.jetbrains.intellij.platform.gradle.artifacts.transform.LocalIvyArtifactPathComponentMetadataRule
plugin.originalFile?.let { pluginPath ->
val jars = collectJars(pluginPath)
jars.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

package org.jetbrains.intellij.platform.gradle.artifacts.transform

import com.jetbrains.plugin.structure.intellij.plugin.IdePluginManager
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.transform.InputArtifact
Expand All @@ -15,20 +14,11 @@ import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileTree
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.Classpath
import org.gradle.kotlin.dsl.registerTransform
import org.gradle.process.ExecOperations
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.intellij.platform.gradle.Constants
import org.jetbrains.intellij.platform.gradle.Constants.Configurations.Attributes
import org.jetbrains.intellij.platform.gradle.Constants.IVY_FILES_DIRECTORY
import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformDependenciesHelper
import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformDependenciesHelper.Companion.collectBundledPluginDependencies
import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformDependenciesHelper.Companion.getBundledPlugins
import org.jetbrains.intellij.platform.gradle.models.IvyModule
import org.jetbrains.intellij.platform.gradle.models.productInfo
import org.jetbrains.intellij.platform.gradle.models.toBundledIvyArtifactsRelativeTo
import org.jetbrains.intellij.platform.gradle.utils.Logger
import org.jetbrains.intellij.platform.gradle.utils.asPath
import org.jetbrains.intellij.platform.gradle.utils.resolvePlatformPath
Expand All @@ -46,7 +36,6 @@ abstract class ExtractorTransformer @Inject constructor(
private val archiveOperations: ArchiveOperations,
private val execOperations: ExecOperations,
private val objectFactory: ObjectFactory,
private val providerFactory: ProviderFactory,
private val fileSystemOperations: FileSystemOperations,
) : TransformAction<TransformParameters.None> {

Expand Down Expand Up @@ -117,66 +106,16 @@ abstract class ExtractorTransformer @Inject constructor(
commandLine("hdiutil", "detach", "-force", "-quiet", tempDirectory)
}
}

else -> {}
}

log.info("Extracting to '$targetDirectory' completed.")

createIvyXmls(targetDirectory.resolvePlatformPath())
}.onFailure {
log.error("${javaClass.canonicalName} execution failed.", it)
}
}

/**
* Pre-create Ivy XML files so that later this directory can be used as an Ivy repository without having to discover
* modules and plugins each time the build is run.
*/
private fun createIvyXmls(platformPath: Path) {
val isIde = platformPath.listDirectoryEntries().map { it.name }.containsAll(
listOf("bin", "lib", "plugins")
)
if (!isIde) {
log.info("The directory '$platformPath' is not an IDE, Ivy repository is not needed there.")
return
}

log.info("Creating an Ivy repository in '$platformPath'.")

val writtenIvyModules = HashSet<String>()
val productInfo = platformPath.productInfo()
val version = productInfo.buildNumber

val pluginManager = IdePluginManager.createManager(createTempDirectory())
val bundledPlugins = platformPath.getBundledPlugins(pluginManager)

bundledPlugins.values.forEach { plugin ->
val pluginId = plugin.pluginId
val pluginVersion = plugin.pluginVersion
val pluginPath = plugin.originalFile
if (null == pluginId || null == pluginVersion || null == pluginPath) {
return@forEach
}

val group = Constants.Configurations.Dependencies.BUNDLED_PLUGIN_GROUP

val ivyDirPath = platformPath.resolve(IVY_FILES_DIRECTORY).absolute().normalize()
IntelliJPlatformDependenciesHelper.writeIvyModule(group, pluginId, version, writtenIvyModules, ivyDirPath) {
val publications = pluginPath.toBundledIvyArtifactsRelativeTo(platformPath)
val dependencies = plugin.collectBundledPluginDependencies(
emptyList(), productInfo, platformPath, bundledPlugins, writtenIvyModules, providerFactory, ivyDirPath
)
IvyModule(
info = IvyModule.Info(group, pluginId, version),
publications = publications,
dependencies = dependencies,
)
}
}

log.info("Creation of an Ivy repository in '$platformPath' finished.")
}

private fun dmgTree(path: Path): FileTree {
log.info("Extracting DMG archive '$path' to temporary directory.")

Expand Down Expand Up @@ -214,7 +153,7 @@ abstract class ExtractorTransformer @Inject constructor(
// such as `.background` meta-directory we have to exclude.
it.file.run {
(name == "Applications" && Files.isSymbolicLink(toPath()))
|| it.relativePath.startsWith('.')
|| it.relativePath.startsWith('.')
}
}
}
Expand All @@ -229,7 +168,8 @@ abstract class ExtractorTransformer @Inject constructor(
intellijPlatformTestClasspath: Configuration,
) {
Attributes.ArtifactType.Archives.forEach {
dependencies.artifactTypes.maybeCreate(it.toString()).attributes.attribute(Attributes.extracted, false)
dependencies.artifactTypes.maybeCreate(it.toString())
.attributes.attribute(Attributes.extracted, false)
}

listOf(compileClasspathConfiguration, testCompileClasspathConfiguration, intellijPlatformClasspath, intellijPlatformTestClasspath).forEach {
Expand Down
Loading

0 comments on commit a4e556c

Please sign in to comment.