diff --git a/CHANGELOG.md b/CHANGELOG.md index 42869528bc..df14da3a37 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## [next] +### 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. + +## [2.1.0] ### Added diff --git a/api/IntelliJPlatformGradlePlugin.api b/api/IntelliJPlatformGradlePlugin.api index 2da140340a..ea7e09ac8b 100644 --- a/api/IntelliJPlatformGradlePlugin.api +++ b/api/IntelliJPlatformGradlePlugin.api @@ -176,6 +176,7 @@ public final class org/jetbrains/intellij/platform/gradle/Constants$Sandbox { public final class org/jetbrains/intellij/platform/gradle/Constants$Tasks { public static final field BUILD_PLUGIN Ljava/lang/String; public static final field BUILD_SEARCHABLE_OPTIONS Ljava/lang/String; + public static final field CLEAN Ljava/lang/String; public static final field COMPOSED_JAR Ljava/lang/String; public static final field GENERATE_MANIFEST Ljava/lang/String; public static final field INITIALIZE_INTELLIJ_PLATFORM_PLUGIN Ljava/lang/String; diff --git a/src/integrationTest/kotlin/org/jetbrains/intellij/platform/gradle/DependencyLockingAndVerificationIntegrationTest.kt b/src/integrationTest/kotlin/org/jetbrains/intellij/platform/gradle/DependencyLockingAndVerificationIntegrationTest.kt new file mode 100644 index 0000000000..ac617f719d --- /dev/null +++ b/src/integrationTest/kotlin/org/jetbrains/intellij/platform/gradle/DependencyLockingAndVerificationIntegrationTest.kt @@ -0,0 +1,108 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.intellij.platform.gradle + +import kotlin.io.path.fileSize +import kotlin.io.path.readText +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Tests dependency locking & verification in combination. + * [DependencyLockingIntegrationTest] + [DependencyVerificationIgnoreIntellijIntegrationTest] but no artifacts are + * ignored in this test. + * [Support dependency verification](https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1779) + */ +class DependencyLockingAndVerificationIntegrationTest : IntelliJPlatformIntegrationTestBase( + resourceName = "dependency-locking-and-verification", +) { + + @Test + @Ignore("https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1779") + fun `build plugin with dependency locks & hash verification`() { + build( + Constants.Tasks.CLEAN, + Constants.Tasks.BUILD_PLUGIN, + projectProperties = defaultProjectProperties, + args = listOf("--info", "--write-locks", "--write-verification-metadata", "md5,sha1,sha256,sha512") + ) { + buildDirectory.resolve("../gradle/locks/root/gradle.lockfile").let { + assertExists(it) + assertTrue(0 < it.fileSize()) + } + buildDirectory.resolve("../gradle/locks/root/gradle-buildscript.lockfile").let { + assertExists(it) + assertTrue(0 < it.fileSize()) + } + buildDirectory.resolve("../gradle/locks/root/settings-gradle-buildscript.lockfile").let { + assertExists(it) + assertTrue(0 < it.fileSize()) + } + buildDirectory.resolve("../gradle/verification-metadata.xml").let { + assertExists(it) + val xmlText = it.readText(Charsets.UTF_8) + assertTrue(xmlText.contains("")) + assertTrue(xmlText.contains("")) + assertTrue(xmlText.contains("")) + assertTrue(xmlText.contains("")) + assertTrue(xmlText.contains("")) + assertTrue(xmlText.contains(" + + + + + true + false + armored + + + + + diff --git a/src/integrationTest/resources/dependency-locking-and-verification/settings.gradle.kts b/src/integrationTest/resources/dependency-locking-and-verification/settings.gradle.kts new file mode 100644 index 0000000000..b5ba1caa0d --- /dev/null +++ b/src/integrationTest/resources/dependency-locking-and-verification/settings.gradle.kts @@ -0,0 +1,12 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +rootProject.name = "test" + +buildscript { + // https://docs.gradle.org/current/userguide/dependency_locking.html + dependencyLocking { + lockAllConfigurations() + lockFile = file("gradle/locks/root/settings-gradle-buildscript.lockfile") + lockMode.set(LockMode.DEFAULT) + //ignoredDependencies.add() + } +} diff --git a/src/integrationTest/resources/dependency-locking/build.gradle.kts b/src/integrationTest/resources/dependency-locking/build.gradle.kts new file mode 100644 index 0000000000..652c379e4a --- /dev/null +++ b/src/integrationTest/resources/dependency-locking/build.gradle.kts @@ -0,0 +1,71 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +import org.jetbrains.intellij.platform.gradle.TestFrameworkType + +val intellijPlatformTypeProperty = providers.gradleProperty("intellijPlatform.type") +val intellijPlatformVersionProperty = providers.gradleProperty("intellijPlatform.version") + +version = "1.0.0" + +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.intellij.platform") +} + +kotlin { + jvmToolchain(17) +} + +buildscript { + // https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1778 + // https://docs.gradle.org/current/userguide/dependency_locking.html + dependencyLocking { + lockAllConfigurations() + lockFile = file("gradle/locks/root/gradle-buildscript.lockfile") + lockMode.set(LockMode.DEFAULT) + //ignoredDependencies.add() + } +} +// https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1778 +// https://docs.gradle.org/current/userguide/dependency_locking.html +dependencyLocking { + lockAllConfigurations() + // There seems to be no way to customize the location of settings-gradle.lockfile + lockFile = file("gradle/locks/root/gradle.lockfile") + lockMode.set(LockMode.DEFAULT) +} + +repositories { + mavenCentral() + + intellijPlatform { + defaultRepositories() + } +} + +dependencies { + intellijPlatform { + create(intellijPlatformTypeProperty, intellijPlatformVersionProperty) + instrumentationTools() + testFramework(TestFrameworkType.Platform) + + // This is important for bug reproduction because we need some dependencies in the test + bundledPlugins( + "com.intellij.copyright", + "com.intellij.java", + "com.intellij.gradle", + "com.intellij.properties", + "org.intellij.groovy", + "com.intellij.java-i18n", + "JUnit", + "org.jetbrains.idea.maven", + "org.jetbrains.idea.eclipse" + ) + } +} + +intellijPlatform { + buildSearchableOptions = false + instrumentCode = false +} + + diff --git a/src/integrationTest/resources/dependency-locking/gradle.properties b/src/integrationTest/resources/dependency-locking/gradle.properties new file mode 100644 index 0000000000..6abec51585 --- /dev/null +++ b/src/integrationTest/resources/dependency-locking/gradle.properties @@ -0,0 +1,2 @@ +# Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +kotlin.stdlib.default.dependency=false diff --git a/src/integrationTest/resources/dependency-locking/settings.gradle.kts b/src/integrationTest/resources/dependency-locking/settings.gradle.kts new file mode 100644 index 0000000000..e4c901ca84 --- /dev/null +++ b/src/integrationTest/resources/dependency-locking/settings.gradle.kts @@ -0,0 +1,13 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +rootProject.name = "test" + +buildscript { + // https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1778 + // https://docs.gradle.org/current/userguide/dependency_locking.html + dependencyLocking { + lockAllConfigurations() + lockFile = file("gradle/locks/root/settings-gradle-buildscript.lockfile") + lockMode.set(LockMode.DEFAULT) + //ignoredDependencies.add() + } +} diff --git a/src/integrationTest/resources/dependency-verification-ignore-intellij/build.gradle.kts b/src/integrationTest/resources/dependency-verification-ignore-intellij/build.gradle.kts new file mode 100644 index 0000000000..4d67cee883 --- /dev/null +++ b/src/integrationTest/resources/dependency-verification-ignore-intellij/build.gradle.kts @@ -0,0 +1,52 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +import org.jetbrains.intellij.platform.gradle.TestFrameworkType + +val intellijPlatformTypeProperty = providers.gradleProperty("intellijPlatform.type") +val intellijPlatformVersionProperty = providers.gradleProperty("intellijPlatform.version") + +version = "1.0.0" + +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.intellij.platform") +} + +kotlin { + jvmToolchain(17) +} + +repositories { + mavenCentral() + + intellijPlatform { + defaultRepositories() + } +} + +dependencies { + intellijPlatform { + create(intellijPlatformTypeProperty, intellijPlatformVersionProperty) + instrumentationTools() + testFramework(TestFrameworkType.Platform) + + // This is important for bug reproduction because we need some dependencies in the test + bundledPlugins( + "com.intellij.copyright", + "com.intellij.java", + "com.intellij.gradle", + "com.intellij.properties", + "org.intellij.groovy", + "com.intellij.java-i18n", + "JUnit", + "org.jetbrains.idea.maven", + "org.jetbrains.idea.eclipse" + ) + } +} + +intellijPlatform { + buildSearchableOptions = false + instrumentCode = false +} + + diff --git a/src/integrationTest/resources/dependency-verification-ignore-intellij/gradle.properties b/src/integrationTest/resources/dependency-verification-ignore-intellij/gradle.properties new file mode 100644 index 0000000000..6abec51585 --- /dev/null +++ b/src/integrationTest/resources/dependency-verification-ignore-intellij/gradle.properties @@ -0,0 +1,2 @@ +# Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +kotlin.stdlib.default.dependency=false diff --git a/src/integrationTest/resources/dependency-verification-ignore-intellij/gradle/verification-metadata.xml b/src/integrationTest/resources/dependency-verification-ignore-intellij/gradle/verification-metadata.xml new file mode 100644 index 0000000000..a16a695df2 --- /dev/null +++ b/src/integrationTest/resources/dependency-verification-ignore-intellij/gradle/verification-metadata.xml @@ -0,0 +1,17 @@ + + + + + + true + false + armored + + + + + + + + + diff --git a/src/integrationTest/resources/dependency-verification-ignore-intellij/settings.gradle.kts b/src/integrationTest/resources/dependency-verification-ignore-intellij/settings.gradle.kts new file mode 100644 index 0000000000..2854026346 --- /dev/null +++ b/src/integrationTest/resources/dependency-verification-ignore-intellij/settings.gradle.kts @@ -0,0 +1,2 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +rootProject.name = "test" diff --git a/src/main/kotlin/org/jetbrains/intellij/platform/gradle/Constants.kt b/src/main/kotlin/org/jetbrains/intellij/platform/gradle/Constants.kt index 491bd625e8..18709d775b 100644 --- a/src/main/kotlin/org/jetbrains/intellij/platform/gradle/Constants.kt +++ b/src/main/kotlin/org/jetbrains/intellij/platform/gradle/Constants.kt @@ -130,6 +130,7 @@ object Constants { } object Tasks { + const val CLEAN = "clean" const val BUILD_PLUGIN = "buildPlugin" const val BUILD_SEARCHABLE_OPTIONS = "buildSearchableOptions" const val COMPOSED_JAR = "composedJar" diff --git a/src/main/kotlin/org/jetbrains/intellij/platform/gradle/artifacts/transform/CollectorTransformer.kt b/src/main/kotlin/org/jetbrains/intellij/platform/gradle/artifacts/transform/CollectorTransformer.kt index 4dcaa7cd7c..ef9c87c4fb 100644 --- a/src/main/kotlin/org/jetbrains/intellij/platform/gradle/artifacts/transform/CollectorTransformer.kt +++ b/src/main/kotlin/org/jetbrains/intellij/platform/gradle/artifacts/transform/CollectorTransformer.kt @@ -27,7 +27,6 @@ import org.jetbrains.intellij.platform.gradle.utils.asPath import org.jetbrains.intellij.platform.gradle.utils.platformPath import org.jetbrains.intellij.platform.gradle.utils.safelyCreatePlugin import java.nio.file.Path -import kotlin.Throws import kotlin.io.path.createTempDirectory import kotlin.io.path.exists import kotlin.io.path.listDirectoryEntries diff --git a/src/main/kotlin/org/jetbrains/intellij/platform/gradle/extensions/IntelliJPlatformDependenciesHelper.kt b/src/main/kotlin/org/jetbrains/intellij/platform/gradle/extensions/IntelliJPlatformDependenciesHelper.kt index 054e792e44..d357f3bbe4 100644 --- a/src/main/kotlin/org/jetbrains/intellij/platform/gradle/extensions/IntelliJPlatformDependenciesHelper.kt +++ b/src/main/kotlin/org/jetbrains/intellij/platform/gradle/extensions/IntelliJPlatformDependenciesHelper.kt @@ -40,9 +40,7 @@ import java.io.File import java.io.FileReader import java.nio.file.Path import java.util.* -import kotlin.Throws import kotlin.io.path.* -import kotlin.math.absoluteValue /** * Helper class for managing dependencies on the IntelliJ Platform in Gradle projects. @@ -697,7 +695,7 @@ class IntelliJPlatformDependenciesHelper( localProductInfo.validateSupportedVersion() val type = localProductInfo.productCode.toIntelliJPlatformType() - val version = "${localProductInfo.buildNumber}+${artifactPath.hash}" + val version = localProductInfo.buildNumber writeIvyModule(Dependencies.LOCAL_IDE_GROUP, type.code, version) { IvyModule( @@ -760,7 +758,7 @@ class IntelliJPlatformDependenciesHelper( } val artifactPath = requireNotNull(plugin.originalFile) - val version = baseVersion.orElse(productInfo.map { it.version }).map { "$it+${artifactPath.hash}" }.get() + val version = baseVersion.orElse(productInfo.map { it.version }).get() writeIvyModule(Dependencies.BUNDLED_PLUGIN_GROUP, id, version) { IvyModule( @@ -792,7 +790,7 @@ class IntelliJPlatformDependenciesHelper( .let { requireNotNull(it) { "Specified bundledModule '$id' doesn't exist." } } val platformPath = platformPath.get() val artifactPaths = bundledModule.classPath.map { path -> platformPath.resolve(path).toIvyArtifact() } - val version = baseVersion.orElse(productInfo.map { it.version }).map { "$it+${platformPath.hash}" }.get() + val version = baseVersion.orElse(productInfo.map { it.version }).get() writeIvyModule(Dependencies.BUNDLED_MODULE_GROUP, id, version) { IvyModule( @@ -830,7 +828,7 @@ class IntelliJPlatformDependenciesHelper( val artifactPath = requireNotNull(plugin.originalFile) val group = Dependencies.BUNDLED_PLUGIN_GROUP val name = requireNotNull(plugin.pluginId) - val version = "${plugin.pluginVersion}+${artifactPath.hash}" + val version = "${plugin.pluginVersion}" writeIvyModule(group, name, version) { IvyModule( @@ -858,7 +856,7 @@ class IntelliJPlatformDependenciesHelper( val artifactPaths = it.classPath.map { path -> platformPath.resolve(path).toIvyArtifact() } val group = Dependencies.BUNDLED_MODULE_GROUP val name = it.name - val version = "$buildNumber+${platformPath.hash}" + val version = buildNumber writeIvyModule(group, name, version) { IvyModule( @@ -894,7 +892,7 @@ class IntelliJPlatformDependenciesHelper( pluginManager.safelyCreatePlugin(pluginPath).getOrThrow() } - val version = (plugin.pluginVersion ?: "0.0.0") + "+" + artifactPath.hash + val version = (plugin.pluginVersion ?: "0.0.0") val name = plugin.pluginId ?: artifactPath.name writeIvyModule(Dependencies.LOCAL_PLUGIN_GROUP, name, version) { @@ -936,7 +934,7 @@ class IntelliJPlatformDependenciesHelper( requireNotNull(javaVersion) val name = javaVendorVersion.substringBefore(javaVersion).trim('-') - val version = javaVendorVersion.removePrefix(name).trim('-') + "+" + artifactPath.hash + val version = javaVendorVersion.removePrefix(name).trim('-') writeIvyModule(Dependencies.LOCAL_JETBRAINS_RUNTIME_GROUP, name, version) { IvyModule( @@ -1094,9 +1092,6 @@ class IntelliJPlatformDependenciesHelper( extension = "zip", ) - private val Path.hash - get() = (absolutePathString().hashCode().absoluteValue % 1000).toString() - internal fun buildJetBrainsRuntimeVersion( version: String, runtimeVariant: String? = null,