Refactor MultiplePluginVersionGradleImportingTestCase
By this commit: - Used `isTeamcityBuild` flag for a separating local run of the tests from CI For local run by default uses master version of gradle-plugin and LATEST_SUPPORTED_GRADLE_VERSION of the Gradle. But you can specify versions for local run by overriding sysenv `IMPORTING_TESTS_LOCAL_RUN_PARAMS`. For example: export IMPORTING_TESTS_LOCAL_RUN_PARAMS=6.7.1:1.4.30 - Moved main logic from `GradleImportingTestCase` to `MultiplePluginVersionGradleImportingTestCase` for removing the first one later - Removed `AbstractModelBuilderTest` as useless only `DistributionLocator` left from this class.
This commit is contained in:
-233
@@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
|
||||||
import com.intellij.openapi.util.io.StreamUtil;
|
|
||||||
import com.intellij.testFramework.IdeaTestUtil;
|
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
|
||||||
import org.codehaus.groovy.runtime.typehandling.ShortTypeHandling;
|
|
||||||
import org.gradle.tooling.BuildActionExecuter;
|
|
||||||
import org.gradle.tooling.GradleConnector;
|
|
||||||
import org.gradle.tooling.ProjectConnection;
|
|
||||||
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
|
|
||||||
import org.gradle.util.GradleVersion;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.plugins.gradle.model.ClassSetProjectImportModelProvider;
|
|
||||||
import org.jetbrains.plugins.gradle.model.ExternalProject;
|
|
||||||
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
|
|
||||||
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
|
|
||||||
import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
|
|
||||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.rules.TestName;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assume.assumeThat;
|
|
||||||
|
|
||||||
// part of org.jetbrains.plugins.gradle.tooling.builder.AbstractModelBuilderTest
|
|
||||||
@RunWith(value = Parameterized.class)
|
|
||||||
public abstract class AbstractModelBuilderTest {
|
|
||||||
|
|
||||||
public static final Object[][] SUPPORTED_GRADLE_VERSIONS = {{"4.9"}, {"5.6.4"}, {"6.1.1"}, {"6.5.1"}};
|
|
||||||
|
|
||||||
private static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]");
|
|
||||||
|
|
||||||
private static File ourTempDir;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final String gradleVersion;
|
|
||||||
private File testDir;
|
|
||||||
private ProjectImportAction.AllModels allModels;
|
|
||||||
|
|
||||||
@Rule public TestName name = new TestName();
|
|
||||||
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
|
|
||||||
|
|
||||||
public AbstractModelBuilderTest(@NotNull String gradleVersion) {
|
|
||||||
this.gradleVersion = gradleVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
|
|
||||||
public static Collection<Object[]> data() {
|
|
||||||
return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
assumeThat(gradleVersion, versionMatcherRule.getMatcher());
|
|
||||||
|
|
||||||
ensureTempDirCreated();
|
|
||||||
|
|
||||||
String methodName = name.getMethodName();
|
|
||||||
Matcher m = TEST_METHOD_NAME_PATTERN.matcher(methodName);
|
|
||||||
if (m.matches()) {
|
|
||||||
methodName = m.group(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
testDir = new File(ourTempDir, methodName);
|
|
||||||
FileUtil.ensureExists(testDir);
|
|
||||||
|
|
||||||
InputStream buildScriptStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.DEFAULT_SCRIPT_NAME);
|
|
||||||
try {
|
|
||||||
FileUtil.writeToFile(
|
|
||||||
new File(testDir, GradleConstants.DEFAULT_SCRIPT_NAME),
|
|
||||||
FileUtil.loadTextAndClose(buildScriptStream)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
StreamUtil.closeStream(buildScriptStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream settingsStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.SETTINGS_FILE_NAME);
|
|
||||||
try {
|
|
||||||
if (settingsStream != null) {
|
|
||||||
FileUtil.writeToFile(
|
|
||||||
new File(testDir, GradleConstants.SETTINGS_FILE_NAME),
|
|
||||||
FileUtil.loadTextAndClose(settingsStream)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
StreamUtil.closeStream(settingsStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
GradleConnector connector = GradleConnector.newConnector();
|
|
||||||
|
|
||||||
URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
|
|
||||||
connector.useDistribution(distributionUri);
|
|
||||||
connector.forProjectDirectory(testDir);
|
|
||||||
int daemonMaxIdleTime = 10;
|
|
||||||
try {
|
|
||||||
daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "10"));
|
|
||||||
}
|
|
||||||
catch (NumberFormatException ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
((DefaultGradleConnector) connector).daemonMaxIdleTime(daemonMaxIdleTime, TimeUnit.SECONDS);
|
|
||||||
ProjectConnection connection = connector.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
ProjectImportAction projectImportAction = new ProjectImportAction(false);
|
|
||||||
projectImportAction.addProjectImportModelProvider(new ClassSetProjectImportModelProvider(getModels()));
|
|
||||||
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
|
|
||||||
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
|
|
||||||
assertNotNull(initScript);
|
|
||||||
String jdkHome = IdeaTestUtil.requireRealJdkHome();
|
|
||||||
buildActionExecutor.setJavaHome(new File(jdkHome));
|
|
||||||
buildActionExecutor.setJvmArguments("-Xmx128m", "-XX:MaxPermSize=64m");
|
|
||||||
buildActionExecutor
|
|
||||||
.withArguments("--info", "--recompile-scripts", GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
|
|
||||||
allModels = buildActionExecutor.run();
|
|
||||||
assertNotNull(allModels);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static Set<Class<?>> getToolingExtensionClasses() {
|
|
||||||
Set<Class<?>> classes = ContainerUtil.set(
|
|
||||||
ExternalProject.class,
|
|
||||||
// gradle-tooling-extension-api jar
|
|
||||||
ProjectImportAction.class,
|
|
||||||
// gradle-tooling-extension-impl jar
|
|
||||||
ModelBuildScriptClasspathBuilderImpl.class,
|
|
||||||
Multimap.class,
|
|
||||||
ShortTypeHandling.class
|
|
||||||
);
|
|
||||||
|
|
||||||
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
|
|
||||||
return classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static Set<Class<?>> doGetToolingExtensionClasses() {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
if (testDir != null) {
|
|
||||||
FileUtil.delete(testDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Set<Class<?>> getModels();
|
|
||||||
|
|
||||||
|
|
||||||
private static void ensureTempDirCreated() throws IOException {
|
|
||||||
if (ourTempDir != null) return;
|
|
||||||
|
|
||||||
ourTempDir = new File(FileUtil.getTempDirectory(), "gradleTests");
|
|
||||||
FileUtil.delete(ourTempDir);
|
|
||||||
FileUtil.ensureExists(ourTempDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DistributionLocator {
|
|
||||||
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
|
|
||||||
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
|
|
||||||
private static final String GRADLE_RELEASE_REPO = "https://services.gradle.org/distributions";
|
|
||||||
private static final String GRADLE_SNAPSHOT_REPO = "https://services.gradle.org/distributions-snapshots";
|
|
||||||
|
|
||||||
@NotNull private final String myReleaseRepoUrl;
|
|
||||||
@NotNull private final String mySnapshotRepoUrl;
|
|
||||||
|
|
||||||
public DistributionLocator() {
|
|
||||||
this(DistributionLocator.getRepoUrl(false), DistributionLocator.getRepoUrl(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
|
|
||||||
myReleaseRepoUrl = releaseRepoUrl;
|
|
||||||
mySnapshotRepoUrl = snapshotRepoUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException {
|
|
||||||
return getDistribution(getDistributionRepository(version), version, "gradle", "bin");
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private String getDistributionRepository(@NotNull GradleVersion version) {
|
|
||||||
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static URI getDistribution(
|
|
||||||
@NotNull String repositoryUrl,
|
|
||||||
@NotNull GradleVersion version,
|
|
||||||
@NotNull String archiveName,
|
|
||||||
@NotNull String archiveClassifier
|
|
||||||
) throws URISyntaxException {
|
|
||||||
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String getRepoUrl(boolean isSnapshotUrl) {
|
|
||||||
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
|
|
||||||
if (envRepoUrl != null) return envRepoUrl;
|
|
||||||
|
|
||||||
return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.
|
||||||
|
*/
|
||||||
|
package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
||||||
|
|
||||||
|
|
||||||
|
import org.gradle.util.GradleVersion;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
public class DistributionLocator {
|
||||||
|
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
|
||||||
|
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
|
||||||
|
private static final String GRADLE_RELEASE_REPO = "https://services.gradle.org/distributions";
|
||||||
|
private static final String GRADLE_SNAPSHOT_REPO = "https://services.gradle.org/distributions-snapshots";
|
||||||
|
|
||||||
|
@NotNull private final String myReleaseRepoUrl;
|
||||||
|
@NotNull private final String mySnapshotRepoUrl;
|
||||||
|
|
||||||
|
public DistributionLocator() {
|
||||||
|
this(getRepoUrl(false), getRepoUrl(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
|
||||||
|
myReleaseRepoUrl = releaseRepoUrl;
|
||||||
|
mySnapshotRepoUrl = snapshotRepoUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException {
|
||||||
|
return getDistribution(getDistributionRepository(version), version, "gradle", "bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String getDistributionRepository(@NotNull GradleVersion version) {
|
||||||
|
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static URI getDistribution(
|
||||||
|
@NotNull String repositoryUrl,
|
||||||
|
@NotNull GradleVersion version,
|
||||||
|
@NotNull String archiveName,
|
||||||
|
@NotNull String archiveClassifier
|
||||||
|
) throws URISyntaxException {
|
||||||
|
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String getRepoUrl(boolean isSnapshotUrl) {
|
||||||
|
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
|
||||||
|
if (envRepoUrl != null) return envRepoUrl;
|
||||||
|
|
||||||
|
return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -17,10 +17,10 @@ abstract class MasterPluginVersionGradleImportingTestCase : MultiplePluginVersio
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Parameterized.Parameters(name = "{index}: Gradle-{0}, KotlinGradlePlugin-{1}")
|
@Parameterized.Parameters(name = "{index}: Gradle-{0}, KotlinGradlePlugin-{1}")
|
||||||
fun data(): Collection<Array<Any>> {
|
fun data(): Collection<Array<Any>> {
|
||||||
return (AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS).map { gradleVersion ->
|
return (SUPPORTED_GRADLE_VERSIONS).map { gradleVersion ->
|
||||||
arrayOf<Any>(
|
arrayOf<Any>(
|
||||||
gradleVersion[0],
|
gradleVersion,
|
||||||
LATEST_SUPPORTED_VERSION
|
MASTER_VERSION_OF_PLUGIN
|
||||||
)
|
)
|
||||||
}.toList()
|
}.toList()
|
||||||
}
|
}
|
||||||
|
|||||||
+467
-54
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2021 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,17 +9,101 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.kotlin.idea.codeInsight.gradle
|
package org.jetbrains.kotlin.idea.codeInsight.gradle
|
||||||
|
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
|
import com.intellij.openapi.application.PathManager
|
||||||
|
import com.intellij.openapi.application.Result
|
||||||
|
import com.intellij.openapi.application.WriteAction
|
||||||
|
import com.intellij.openapi.externalSystem.importing.ImportSpec
|
||||||
|
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||||
|
import com.intellij.openapi.externalSystem.model.ProjectSystemId
|
||||||
|
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings
|
||||||
|
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
|
||||||
|
import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
|
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||||
|
import com.intellij.openapi.fileEditor.impl.LoadTextUtil
|
||||||
|
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.projectRoots.JavaSdk
|
||||||
|
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||||
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
|
import com.intellij.openapi.projectRoots.impl.ProjectJdkTableImpl
|
||||||
|
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||||
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
|
import com.intellij.openapi.ui.Messages
|
||||||
|
import com.intellij.openapi.ui.TestDialog
|
||||||
|
import com.intellij.openapi.util.Disposer
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||||
|
import com.intellij.testFramework.IdeaTestUtil
|
||||||
|
import com.intellij.testFramework.RunAll
|
||||||
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
|
import com.intellij.testFramework.VfsTestUtil
|
||||||
|
import com.intellij.util.ArrayUtilRt
|
||||||
|
import com.intellij.util.PathUtil
|
||||||
|
import com.intellij.util.SmartList
|
||||||
|
import com.intellij.util.ThrowableRunnable
|
||||||
|
import com.intellij.util.containers.ContainerUtil
|
||||||
|
import junit.framework.TestCase
|
||||||
|
import org.gradle.StartParameter
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
import org.gradle.wrapper.GradleWrapperMain
|
||||||
|
import org.gradle.wrapper.PathAssembler
|
||||||
|
import org.intellij.lang.annotations.Language
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.kotlin.idea.test.GradleProcessOutputInterceptor
|
||||||
|
import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker
|
||||||
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
|
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
|
||||||
|
import org.jetbrains.kotlin.test.JUnitParameterizedWithIdeaConfigurationRunner
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.jetbrains.kotlin.test.RunnerFactoryWithMuteInDatabase
|
||||||
|
import org.jetbrains.plugins.gradle.settings.DistributionType
|
||||||
|
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||||
|
import org.jetbrains.plugins.gradle.settings.GradleSettings
|
||||||
|
import org.jetbrains.plugins.gradle.settings.GradleSystemSettings
|
||||||
|
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||||
|
import org.jetbrains.plugins.gradle.util.GradleUtil
|
||||||
|
import org.jetbrains.plugins.groovy.GroovyFileType
|
||||||
|
import org.junit.Assume
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
import org.junit.rules.TestName
|
||||||
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.Parameterized
|
import org.junit.runners.Parameterized
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.StringWriter
|
||||||
|
import java.net.URISyntaxException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.zip.ZipException
|
||||||
|
import java.util.zip.ZipFile
|
||||||
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
const val mppImportTestMinVersionForMaster = "6.1+"
|
@RunWith(value = JUnitParameterizedWithIdeaConfigurationRunner::class)
|
||||||
const val legacyMppImportTestMinVersionForMaster = "6.1+"
|
@Parameterized.UseParametersRunnerFactory(RunnerFactoryWithMuteInDatabase::class)
|
||||||
|
abstract class MultiplePluginVersionGradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||||
|
protected var sdkCreationChecker: KotlinSdkCreationChecker? = null
|
||||||
|
|
||||||
|
private val removedSdks: MutableList<Sdk> = SmartList()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@Rule
|
||||||
|
var name = TestName()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@Rule
|
||||||
|
var testWatcher = ImportingTestWatcher()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@Parameterized.Parameter(0)
|
||||||
|
var gradleVersion: String = ""
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@Parameterized.Parameter(1)
|
||||||
|
var gradleKotlinPluginVersion: String = ""
|
||||||
|
|
||||||
abstract class MultiplePluginVersionGradleImportingTestCase : GradleImportingTestCase() {
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
var pluginVersionMatchingRule = PluginTargetVersionsRule()
|
var pluginVersionMatchingRule = PluginTargetVersionsRule()
|
||||||
@@ -27,76 +111,405 @@ abstract class MultiplePluginVersionGradleImportingTestCase : GradleImportingTes
|
|||||||
val project: Project
|
val project: Project
|
||||||
get() = myProject
|
get() = myProject
|
||||||
|
|
||||||
|
private val isMasterVersion: Boolean
|
||||||
|
get() = gradleKotlinPluginVersion == MASTER_VERSION_OF_PLUGIN
|
||||||
|
|
||||||
override fun isApplicableTest(): Boolean {
|
open fun isApplicableTest(): Boolean {
|
||||||
return pluginVersionMatchingRule.matches(
|
return pluginVersionMatchingRule.matches(
|
||||||
gradleVersion, gradleKotlinPluginVersion,
|
gradleVersion,
|
||||||
gradleKotlinPluginVersionType == LATEST_SUPPORTED_VERSION
|
gradleKotlinPluginVersion.substringBefore("-"),
|
||||||
|
isMasterVersion
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun importProject() {
|
private lateinit var myProjectSettings: GradleProjectSettings
|
||||||
super.importProject(skipIndexing = true)
|
private lateinit var myJdkHome: String
|
||||||
|
|
||||||
|
open fun jvmHeapArgsByGradleVersion(version: String): String = when {
|
||||||
|
version.startsWith("4.") ->
|
||||||
|
// work-around due to memory leak in class loaders in gradle. The amount of used memory in the gradle daemon
|
||||||
|
// is drammatically increased on every reimport of project due to sequential compilation of build scripts.
|
||||||
|
// see more details in https://github.com/gradle/gradle/commit/b483d29f315758913791fe58d572fa6bafa0395c
|
||||||
|
"-Xmx256m -XX:MaxPermSize=64m"
|
||||||
|
else ->
|
||||||
|
// 128M should be enough for gradle 5.0+ (leak is fixed), and <4.0 (amount of tests is less)
|
||||||
|
"-Xms128M -Xmx192m -XX:MaxPermSize=64m"
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmField
|
override fun setUp() {
|
||||||
@Parameterized.Parameter(1)
|
myJdkHome = IdeaTestUtil.requireRealJdkHome()
|
||||||
var gradleKotlinPluginVersionType: String = MINIMAL_SUPPORTED_VERSION
|
super.setUp()
|
||||||
|
Assume.assumeTrue(isApplicableTest())
|
||||||
|
removedSdks.clear()
|
||||||
|
runWrite {
|
||||||
|
val jdkTable = getProjectJdkTableSafe()
|
||||||
|
jdkTable.findJdk(GRADLE_JDK_NAME)?.let { jdkTable.removeJdk(it) }
|
||||||
|
val jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(File(myJdkHome))!!
|
||||||
|
val jdk = SdkConfigurationUtil.setupSdk(
|
||||||
|
arrayOfNulls(0), jdkHomeDir, JavaSdk.getInstance(), true, null,
|
||||||
|
GRADLE_JDK_NAME
|
||||||
|
)
|
||||||
|
TestCase.assertNotNull("Cannot create JDK for $myJdkHome", jdk)
|
||||||
|
if (!jdkTable.allJdks.contains(jdk)) {
|
||||||
|
(jdkTable as ProjectJdkTableImpl).addTestJdk(jdk!!, testRootDisposable)
|
||||||
|
ProjectRootManager.getInstance(myProject).projectSdk = jdk
|
||||||
|
}
|
||||||
|
FileTypeManager.getInstance().associateExtension(GroovyFileType.GROOVY_FILE_TYPE, "gradle")
|
||||||
|
}
|
||||||
|
myProjectSettings = GradleProjectSettings().apply {
|
||||||
|
this.isUseQualifiedModuleNames = false
|
||||||
|
}
|
||||||
|
System.setProperty(
|
||||||
|
ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY,
|
||||||
|
GRADLE_DAEMON_TTL_MS.toString()
|
||||||
|
)
|
||||||
|
|
||||||
val gradleKotlinPluginVersion: String
|
val distribution = WriteAction.computeAndWait<PathAssembler.LocalDistribution, Throwable> { configureWrapper() }
|
||||||
get() = KOTLIN_GRADLE_PLUGIN_VERSION_DESCRIPTION_TO_VERSION[gradleKotlinPluginVersionType] ?: gradleKotlinPluginVersionType
|
|
||||||
|
val allowedRoots = ArrayList<String>()
|
||||||
|
collectAllowedRoots(allowedRoots, distribution)
|
||||||
|
if (allowedRoots.isNotEmpty()) {
|
||||||
|
VfsRootAccess.allowRootAccess(myTestFixture.testRootDisposable, *ArrayUtilRt.toStringArray(allowedRoots))
|
||||||
|
}
|
||||||
|
|
||||||
|
GradleSettings.getInstance(myProject).gradleVmOptions =
|
||||||
|
"${jvmHeapArgsByGradleVersion(gradleVersion)} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}"
|
||||||
|
|
||||||
|
sdkCreationChecker = KotlinSdkCreationChecker()
|
||||||
|
|
||||||
|
GradleProcessOutputInterceptor.install(testRootDisposable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tearDown() {
|
||||||
|
RunAll(
|
||||||
|
ThrowableRunnable {
|
||||||
|
runWrite {
|
||||||
|
Arrays.stream(ProjectJdkTable.getInstance().allJdks).forEach { jdk: Sdk ->
|
||||||
|
(ProjectJdkTable.getInstance() as ProjectJdkTableImpl).removeTestJdk(jdk)
|
||||||
|
if (jdk is Disposable) {
|
||||||
|
Disposer.dispose((jdk as Disposable))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removedSdks.forEach { sdk -> SdkConfigurationUtil.addSdk(sdk) }
|
||||||
|
removedSdks.clear()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ThrowableRunnable {
|
||||||
|
Messages.setTestDialog(TestDialog.DEFAULT)
|
||||||
|
deleteBuildSystemDirectory()
|
||||||
|
// was FileUtil.delete(BuildManager.getInstance().buildSystemDirectory.toFile())
|
||||||
|
sdkCreationChecker?.removeNewKotlinSdk()
|
||||||
|
},
|
||||||
|
ThrowableRunnable {
|
||||||
|
super.tearDown()
|
||||||
|
}
|
||||||
|
).run()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun collectAllowedRoots(roots: MutableList<String>) {
|
||||||
|
super.collectAllowedRoots(roots)
|
||||||
|
roots.add(myJdkHome)
|
||||||
|
roots.addAll(ExternalSystemTestCase.collectRootsInside(myJdkHome))
|
||||||
|
roots.add(PathManager.getConfigPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun collectAllowedRoots(
|
||||||
|
roots: MutableList<String>,
|
||||||
|
distribution: PathAssembler.LocalDistribution?
|
||||||
|
) {
|
||||||
|
//Note: could be required to use:
|
||||||
|
//Environment.getEnvVariable("JAVA_HOME")
|
||||||
|
roots.add(myJdkHome)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return if (name.methodName == null) super.getName() else FileUtil.sanitizeFileName(name.methodName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExternalSystemConfigFileName(): String = "build.gradle"
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
protected open fun importProjectUsingSingeModulePerGradleProject(config: String? = null, skipIndexing: Boolean? = null) {
|
||||||
|
currentExternalProjectSettings.isResolveModulePerSourceSet = false
|
||||||
|
importProject(config, skipIndexing)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun importProject() {
|
||||||
|
importProject(skipIndexing = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun importProject(skipIndexing: Boolean?) {
|
||||||
|
ExternalSystemApiUtil.subscribe(
|
||||||
|
myProject,
|
||||||
|
GradleConstants.SYSTEM_ID,
|
||||||
|
object : ExternalSystemSettingsListenerAdapter<ExternalProjectSettings>() {
|
||||||
|
override fun onProjectsLinked(settings: Collection<ExternalProjectSettings>) {
|
||||||
|
val item = ContainerUtil.getFirstItem<Any>(settings)
|
||||||
|
if (item is GradleProjectSettings) {
|
||||||
|
item.gradleJvm = GRADLE_JDK_NAME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
super.importProject(skipIndexing)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun importProject(@NonNls @Language("Groovy") config: String?, skipIndexing: Boolean?) {
|
||||||
|
var config = config
|
||||||
|
config = injectRepo(config)
|
||||||
|
super.importProject(config, skipIndexing)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handleImportFailure(errorMessage: String, errorDetails: String?) {
|
||||||
|
val gradleOutput = GradleProcessOutputInterceptor.getInstance()?.getOutput().orEmpty()
|
||||||
|
|
||||||
|
// Typically Gradle error message consists of a line with the description of the error followed by
|
||||||
|
// a multi-line stacktrace. The idea is to cut off the stacktrace if it is already contained in
|
||||||
|
// the intercepted Gradle process output to avoid unnecessary verbosity.
|
||||||
|
val compactErrorMessage = when (val indexOfNewLine = errorMessage.indexOf('\n')) {
|
||||||
|
-1 -> errorMessage
|
||||||
|
else -> {
|
||||||
|
val compactErrorMessage = errorMessage.substring(0, indexOfNewLine)
|
||||||
|
val theRest = errorMessage.substring(indexOfNewLine + 1)
|
||||||
|
if (theRest in gradleOutput) compactErrorMessage else errorMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val failureMessage = buildString {
|
||||||
|
append("Gradle import failed: ").append(compactErrorMessage).append('\n')
|
||||||
|
if (!errorDetails.isNullOrBlank()) append("Error details: ").append(errorDetails).append('\n')
|
||||||
|
append("Gradle process output (BEGIN):\n")
|
||||||
|
append(gradleOutput)
|
||||||
|
if (!gradleOutput.endsWith('\n')) append('\n')
|
||||||
|
append("Gradle process output (END)")
|
||||||
|
}
|
||||||
|
fail(failureMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun injectRepo(@NonNls @Language("Groovy") config: String?): String {
|
||||||
|
var config = config ?: ""
|
||||||
|
config = """allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'https://repo.labs.intellij.net/repo1'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
$config"""
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createImportSpec(): ImportSpec? {
|
||||||
|
val importSpecBuilder = ImportSpecBuilder(super.createImportSpec())
|
||||||
|
importSpecBuilder.withArguments("--stacktrace")
|
||||||
|
return importSpecBuilder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCurrentExternalProjectSettings(): GradleProjectSettings = myProjectSettings
|
||||||
|
|
||||||
|
override fun getExternalSystemId(): ProjectSystemId = GradleConstants.SYSTEM_ID
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
protected open fun createSettingsFile(@NonNls @Language("Groovy") content: String?): VirtualFile? {
|
||||||
|
return createProjectSubFile("settings.gradle", content)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun testDataDirName(): String = ""
|
||||||
|
|
||||||
|
protected open fun testDataDirectory(): File {
|
||||||
|
val baseDir = "${PluginTestCaseBase.getTestDataPathBase()}/gradle/${testDataDirName()}/"
|
||||||
|
return File(baseDir, getTestName(true).substringBefore("_"))
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun configureKotlinVersionAndProperties(text: String, properties: Map<String, String>? = null): String {
|
||||||
|
var result = text
|
||||||
|
(properties ?: getDefaultPropertiesMap()).forEach { (key, value) ->
|
||||||
|
result = result.replace("{{${key}}}", value)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun configureByFiles(properties: Map<String, String>? = null): List<VirtualFile> {
|
||||||
|
val rootDir = testDataDirectory()
|
||||||
|
assert(rootDir.exists()) { "Directory ${rootDir.path} doesn't exist" }
|
||||||
|
|
||||||
|
val unitedProperties = HashMap(properties ?: emptyMap()).apply { putAll(getDefaultPropertiesMap()) }
|
||||||
|
|
||||||
|
return rootDir.walk().mapNotNull {
|
||||||
|
when {
|
||||||
|
it.isDirectory -> null
|
||||||
|
|
||||||
|
!it.name.endsWith(SUFFIX) -> {
|
||||||
|
val text =
|
||||||
|
configureKotlinVersionAndProperties(FileUtil.loadFile(it, /* convertLineSeparators = */ true), unitedProperties)
|
||||||
|
val virtualFile = createProjectSubFile(it.path.substringAfter(rootDir.path + File.separator), text)
|
||||||
|
|
||||||
|
// Real file with expected testdata allows to throw nicer exceptions in
|
||||||
|
// case of mismatch, as well as open interactive diff window in IDEA
|
||||||
|
virtualFile.putUserData(VfsTestUtil.TEST_DATA_FILE_PATH, it.absolutePath)
|
||||||
|
|
||||||
|
virtualFile
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun importProjectFromTestData(skipIndexing: Boolean? = null): List<VirtualFile> {
|
||||||
|
val files = configureByFiles()
|
||||||
|
importProject(skipIndexing)
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun checkFiles(files: List<VirtualFile>) {
|
||||||
|
FileDocumentManager.getInstance().saveAllDocuments()
|
||||||
|
|
||||||
|
files.filter {
|
||||||
|
it.name == GradleConstants.DEFAULT_SCRIPT_NAME
|
||||||
|
|| it.name == GradleConstants.KOTLIN_DSL_SCRIPT_NAME
|
||||||
|
|| it.name == GradleConstants.SETTINGS_FILE_NAME
|
||||||
|
}
|
||||||
|
.forEach {
|
||||||
|
if (it.name == GradleConstants.SETTINGS_FILE_NAME && !File(testDataDirectory(), it.name + SUFFIX).exists()) return@forEach
|
||||||
|
val actualText = configureKotlinVersionAndProperties(LoadTextUtil.loadText(it).toString())
|
||||||
|
val expectedFileName = if (File(testDataDirectory(), it.name + ".$gradleVersion" + SUFFIX).exists()) {
|
||||||
|
it.name + ".$gradleVersion" + SUFFIX
|
||||||
|
} else {
|
||||||
|
it.name + SUFFIX
|
||||||
|
}
|
||||||
|
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory(), expectedFileName), actualText)
|
||||||
|
{ s -> configureKotlinVersionAndProperties(s) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun enableGradleDebugWithSuspend() {
|
||||||
|
GradleSystemSettings.getInstance().gradleVmOptions = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class, URISyntaxException::class)
|
||||||
|
private fun configureWrapper(): PathAssembler.LocalDistribution {
|
||||||
|
val distributionUri = DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion))
|
||||||
|
|
||||||
|
myProjectSettings.distributionType = DistributionType.DEFAULT_WRAPPED
|
||||||
|
val wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(wrapperJar())!!
|
||||||
|
|
||||||
|
val wrapperJarFromTo = createProjectSubFile("gradle/wrapper/gradle-wrapper.jar")
|
||||||
|
runWrite {
|
||||||
|
wrapperJarFromTo.setBinaryContent(wrapperJarFrom.contentsToByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
val properties = Properties()
|
||||||
|
properties.setProperty("distributionBase", "GRADLE_USER_HOME")
|
||||||
|
properties.setProperty("distributionPath", "wrapper/dists")
|
||||||
|
properties.setProperty("zipStoreBase", "GRADLE_USER_HOME")
|
||||||
|
properties.setProperty("zipStorePath", "wrapper/dists")
|
||||||
|
properties.setProperty("distributionUrl", distributionUri.toString())
|
||||||
|
|
||||||
|
val writer = StringWriter()
|
||||||
|
properties.store(writer, null)
|
||||||
|
|
||||||
|
createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString())
|
||||||
|
|
||||||
|
val wrapperConfiguration =
|
||||||
|
GradleUtil.getWrapperConfiguration(projectPath)
|
||||||
|
val localDistribution = PathAssembler(
|
||||||
|
StartParameter.DEFAULT_GRADLE_USER_HOME
|
||||||
|
).getDistribution(wrapperConfiguration)
|
||||||
|
|
||||||
|
val zip = localDistribution.zipFile
|
||||||
|
try {
|
||||||
|
if (zip.exists()) {
|
||||||
|
val zipFile = ZipFile(zip)
|
||||||
|
zipFile.close()
|
||||||
|
}
|
||||||
|
} catch (e: ZipException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
println("Corrupted file will be removed: " + zip.path)
|
||||||
|
FileUtil.delete(zip)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return localDistribution
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runWrite(f: () -> Unit) {
|
||||||
|
object : WriteAction<Any>() {
|
||||||
|
override fun run(result: Result<Any>) {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefaultPropertiesMap(): Map<String, String> {
|
||||||
|
val defaultProperties = HashMap<String, String>()
|
||||||
|
defaultProperties["kotlin_plugin_version"] = gradleKotlinPluginVersion
|
||||||
|
defaultProperties["kotlin_plugin_repositories"] = repositories(false)
|
||||||
|
defaultProperties["kts_kotlin_plugin_repositories"] = repositories(true)
|
||||||
|
|
||||||
|
return defaultProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun repositories(useKts: Boolean): String {
|
||||||
|
val customRepositories = arrayOf(
|
||||||
|
"https://dl.bintray.com/kotlin/kotlin-dev",
|
||||||
|
)
|
||||||
|
val customMavenRepositories = customRepositories.joinToString("\n") { if (useKts) "maven(\"$it\")" else "maven { url '$it' } " }
|
||||||
|
return """
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
$customMavenRepositories
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun wrapperJar(): File {
|
||||||
|
return File(PathUtil.getJarPathForClass(GradleWrapperMain::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MINIMAL_SUPPORTED_VERSION = "minimal"// minimal supported version
|
const val GRADLE_JDK_NAME = "Gradle JDK"
|
||||||
const val LATEST_STABLE_VERSUON = "latest stable"
|
private const val GRADLE_DAEMON_TTL_MS = 10000
|
||||||
const val LATEST_SUPPORTED_VERSION = "master"// gradle plugin from current build
|
|
||||||
|
|
||||||
//should be extended with LATEST_SUPPORTED_VERSION
|
@JvmStatic
|
||||||
private val KOTLIN_GRADLE_PLUGIN_VERSIONS = listOf(MINIMAL_SUPPORTED_VERSION, LATEST_STABLE_VERSUON, LATEST_SUPPORTED_VERSION)
|
protected val SUFFIX = ".after"
|
||||||
private val KOTLIN_GRADLE_PLUGIN_VERSION_DESCRIPTION_TO_VERSION = mapOf(
|
|
||||||
MINIMAL_SUPPORTED_VERSION to MINIMAL_SUPPORTED_GRADLE_PLUGIN_VERSION,
|
|
||||||
LATEST_STABLE_VERSUON to LATEST_STABLE_GRADLE_PLUGIN_VERSION,
|
|
||||||
LATEST_SUPPORTED_VERSION to readPluginVersion()
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun readPluginVersion() =
|
const val RELEASED_A_YEAR_AGO_GRADLE_PLUGIN_VERSION = "1.3.72"
|
||||||
File("libraries/tools/kotlin-gradle-plugin/build/libs").listFiles()?.map { it.name }
|
const val LATEST_STABLE_RELEASE_GRADLE_PLUGIN_VERSION = "1.4.30"
|
||||||
|
val MASTER_VERSION_OF_PLUGIN
|
||||||
|
get() = File("libraries/tools/kotlin-gradle-plugin/build/libs").listFiles()?.map { it.name }
|
||||||
?.firstOrNull { it.contains("-original.jar") }?.replace(
|
?.firstOrNull { it.contains("-original.jar") }?.replace(
|
||||||
"kotlin-gradle-plugin-",
|
"kotlin-gradle-plugin-",
|
||||||
""
|
""
|
||||||
)?.replace("-original.jar", "") ?: "1.5.255-SNAPSHOT"
|
)?.replace("-original.jar", "") ?: "1.5.255-SNAPSHOT"
|
||||||
|
|
||||||
|
const val LATEST_SUPPORTED_GRADLE_VERSION = "6.5.1"
|
||||||
|
|
||||||
|
val SUPPORTED_GRADLE_VERSIONS = arrayOf("4.9", "5.6.4", LATEST_SUPPORTED_GRADLE_VERSION)
|
||||||
|
|
||||||
|
private val LOCAL_RUN_PARAMS: Array<Any> =
|
||||||
|
System.getenv("IMPORTING_TESTS_LOCAL_RUN_PARAMS") // You can specify versions for local run. For example: "6.7.1:1.4.30"
|
||||||
|
?.replace(" ", "")
|
||||||
|
?.split(":")?.toTypedArray()
|
||||||
|
?: arrayOf(LATEST_SUPPORTED_GRADLE_VERSION, MASTER_VERSION_OF_PLUGIN)
|
||||||
|
|
||||||
|
private val isTeamcityBuild = UsefulTestCase.IS_UNDER_TEAMCITY
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Parameterized.Parameters(name = "{index}: Gradle-{0}, KotlinGradlePlugin-{1}")
|
@Parameterized.Parameters(name = "{index}: Gradle-{0}, KotlinGradlePlugin-{1}")
|
||||||
fun data(): Collection<Array<Any>> {
|
fun data(): Collection<Array<Any>> {
|
||||||
return (AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS).flatMap { gradleVersion ->
|
if (isTeamcityBuild)
|
||||||
KOTLIN_GRADLE_PLUGIN_VERSIONS.map { kotlinVersion ->
|
return listOf(LOCAL_RUN_PARAMS)
|
||||||
arrayOf<Any>(
|
|
||||||
gradleVersion[0],
|
return (SUPPORTED_GRADLE_VERSIONS).flatMap { gradleVersion ->
|
||||||
kotlinVersion
|
arrayOf(
|
||||||
)
|
RELEASED_A_YEAR_AGO_GRADLE_PLUGIN_VERSION,
|
||||||
|
LATEST_STABLE_RELEASE_GRADLE_PLUGIN_VERSION,
|
||||||
|
MASTER_VERSION_OF_PLUGIN
|
||||||
|
).map { pluginVersion ->
|
||||||
|
arrayOf(gradleVersion, pluginVersion)
|
||||||
}
|
}
|
||||||
}.toList()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fun repositories(useKts: Boolean): String {
|
|
||||||
return """
|
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
gradlePluginPortal()
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
""".trimIndent()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun configureByFiles(properties: Map<String, String>?): List<VirtualFile> {
|
|
||||||
val unitedProperties = HashMap(properties ?: emptyMap())
|
|
||||||
unitedProperties["kotlin_plugin_version"] = gradleKotlinPluginVersion
|
|
||||||
|
|
||||||
unitedProperties["kotlin_plugin_repositories"] = repositories(false)
|
|
||||||
unitedProperties["kts_kotlin_plugin_repositories"] = repositories(true)
|
|
||||||
return super.configureByFiles(unitedProperties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+31
-20
@@ -4,20 +4,25 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
||||||
|
|
||||||
import org.gradle.util.GradleVersion;
|
|
||||||
import org.hamcrest.CustomMatcher;
|
import org.hamcrest.CustomMatcher;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.plugins.gradle.tooling.annotation.PluginTargetVersions;
|
import org.jetbrains.plugins.gradle.tooling.annotation.PluginTargetVersions;
|
||||||
import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions;
|
import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions;
|
||||||
import org.jetbrains.plugins.gradle.tooling.util.VersionMatcher;
|
|
||||||
import org.junit.rules.TestWatcher;
|
import org.junit.rules.TestWatcher;
|
||||||
import org.junit.runner.Description;
|
import org.junit.runner.Description;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
// modified copy of org.jetbrains.plugins.gradle.tooling.VersionMatcherRule
|
// modified copy of org.jetbrains.plugins.gradle.tooling.VersionMatcherRule
|
||||||
public class PluginTargetVersionsRule extends TestWatcher {
|
public class PluginTargetVersionsRule extends TestWatcher {
|
||||||
|
|
||||||
|
private final String[][] versionRules = {{"1.3.0 <=> 1.4.0", "4.0+"}, {"1.4.0+", "6.0+"}};
|
||||||
|
//Specify rules for different version Kotlin Gradle plugin and Gradle
|
||||||
|
|
||||||
private class TargetVersionsImpl implements TargetVersions {
|
private class TargetVersionsImpl implements TargetVersions {
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
@@ -41,40 +46,46 @@ public class PluginTargetVersionsRule extends TestWatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CustomMatcher<String> gradleVersionMatcher;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private CustomMatcher gradleVersionMatcher;
|
private CustomMatcher<String> pluginVersionMatcher;
|
||||||
|
|
||||||
@Nullable
|
private boolean skipForMaster;
|
||||||
private CustomMatcher pluginVersionMatcher;
|
|
||||||
|
|
||||||
@Nullable
|
private final List<CustomMatcher<String>[]> versionCombinationsMatcher = new ArrayList<>();
|
||||||
private CustomMatcher gradleVersionMatcherForLatestPlugin;
|
|
||||||
|
|
||||||
@NotNull
|
public boolean matches(String gradleVersion, String pluginVersion, boolean isMaster) {
|
||||||
public boolean matches(String gradleVersion, String pluginVersion, boolean isLatestPluginVersion) {
|
if (skipForMaster && isMaster) {
|
||||||
boolean matchGradleVersion = gradleVersionMatcher == null || gradleVersionMatcher.matches(gradleVersion);
|
return false;
|
||||||
if (isLatestPluginVersion) {
|
|
||||||
if (gradleVersionMatcherForLatestPlugin != null) {
|
|
||||||
return gradleVersionMatcherForLatestPlugin.matches(gradleVersion);
|
|
||||||
}
|
|
||||||
return matchGradleVersion;
|
|
||||||
}
|
}
|
||||||
|
boolean matchGradleVersion = gradleVersionMatcher == null || gradleVersionMatcher.matches(gradleVersion);
|
||||||
boolean pluginVersionMatches = pluginVersionMatcher == null || pluginVersionMatcher.matches(pluginVersion);
|
boolean pluginVersionMatches = pluginVersionMatcher == null || pluginVersionMatcher.matches(pluginVersion);
|
||||||
return matchGradleVersion && pluginVersionMatches;
|
return matchGradleVersion && pluginVersionMatches &&
|
||||||
|
versionCombinationsMatcher.stream().anyMatch(i -> i[0].matches(pluginVersion) && i[1].matches(gradleVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
protected void starting(Description d) {
|
protected void starting(Description d) {
|
||||||
final PluginTargetVersions pluginTargetVersions = d.getAnnotation(PluginTargetVersions.class);
|
Arrays.stream(versionRules).forEach(i -> versionCombinationsMatcher.add(
|
||||||
|
new CustomMatcher[] {
|
||||||
|
VersionMatcherRule.produceMatcher("Plugin", new TargetVersionsImpl(i[0])),
|
||||||
|
VersionMatcherRule.produceMatcher("Gradle", new TargetVersionsImpl(i[1]))
|
||||||
|
}));
|
||||||
|
|
||||||
|
PluginTargetVersions pluginTargetVersions = d.getAnnotation(PluginTargetVersions.class);
|
||||||
if (d.getAnnotation(TargetVersions.class) != null && pluginTargetVersions != null) {
|
if (d.getAnnotation(TargetVersions.class) != null && pluginTargetVersions != null) {
|
||||||
throw new IllegalArgumentException(String.format("Annotations %s and %s could not be used together. ",
|
throw new IllegalArgumentException(String.format("Annotations %s and %s could not be used together. ",
|
||||||
TargetVersions.class.getName(), PluginTargetVersions.class.getName()));
|
TargetVersions.class.getName(), PluginTargetVersions.class.getName()));
|
||||||
}
|
}
|
||||||
if (pluginTargetVersions == null) return;
|
if (pluginTargetVersions == null) return;
|
||||||
|
|
||||||
gradleVersionMatcher = pluginTargetVersions.gradleVersion().isEmpty() ? null : VersionMatcherRule.produceMatcher("Gradle", new TargetVersionsImpl(pluginTargetVersions.gradleVersion()));
|
gradleVersionMatcher = pluginTargetVersions.gradleVersion().isEmpty() ? null : VersionMatcherRule
|
||||||
pluginVersionMatcher = pluginTargetVersions.pluginVersion().isEmpty() ? null : VersionMatcherRule.produceMatcher("Plugin", new TargetVersionsImpl(pluginTargetVersions.pluginVersion()));
|
.produceMatcher("Gradle", new TargetVersionsImpl(pluginTargetVersions.gradleVersion()));
|
||||||
gradleVersionMatcherForLatestPlugin = pluginTargetVersions.gradleVersionForLatestPlugin().isEmpty() ? null : VersionMatcherRule.produceMatcher("Gradle for latest plugin", new TargetVersionsImpl(pluginTargetVersions.gradleVersionForLatestPlugin()));
|
pluginVersionMatcher = pluginTargetVersions.pluginVersion().isEmpty() ? null : VersionMatcherRule
|
||||||
|
.produceMatcher("Plugin", new TargetVersionsImpl(pluginTargetVersions.pluginVersion()));
|
||||||
|
skipForMaster = pluginTargetVersions.skipForMaster();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,5 +16,5 @@ public @interface PluginTargetVersions {
|
|||||||
|
|
||||||
String pluginVersion() default "1.3.50+";
|
String pluginVersion() default "1.3.50+";
|
||||||
|
|
||||||
String gradleVersionForLatestPlugin() default "";
|
boolean skipForMaster() default false;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user