KT-10114 Maven: plugin doesn't recognize sourceDirs configured in the goal configuration

This commit is contained in:
Sergey Mashkov
2015-11-20 15:43:31 +03:00
parent 46f4191185
commit 2f04f30063
6 changed files with 1789 additions and 0 deletions
+8
View File
@@ -3,4 +3,12 @@
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJavaMavenConfigurator"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJavascriptMavenConfigurator"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.idea.maven">
<importer implementation="org.jetbrains.kotlin.idea.configuration.KotlinMavenImporter" />
</extensions>
<module-components>
<component>
<implementation-class>org.jetbrains.kotlin.idea.configuration.KotlinImporterComponent</implementation-class>
</component>
</module-components>
</idea-plugin>
@@ -0,0 +1,139 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.components.*
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.module.Module
import org.jdom.Element
import org.jetbrains.idea.maven.importing.MavenImporter
import org.jetbrains.idea.maven.importing.MavenRootModelAdapter
import org.jetbrains.idea.maven.model.MavenPlugin
import org.jetbrains.idea.maven.project.MavenProject
import org.jetbrains.idea.maven.project.MavenProjectChanges
import org.jetbrains.idea.maven.project.MavenProjectsProcessorTask
import org.jetbrains.idea.maven.project.MavenProjectsTree
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import java.io.File
import java.util.*
private val KotlinPluginGroupId = "org.jetbrains.kotlin"
private val KotlinPluginArtifactId = "kotlin-maven-plugin"
private val KotlinPluginSourceDirsConfig = "sourceDirs"
class KotlinMavenImporter : MavenImporter(KotlinPluginGroupId, KotlinPluginArtifactId) {
override fun preProcess(module: Module, mavenProject: MavenProject, changes: MavenProjectChanges, modifiableModelsProvider: IdeModifiableModelsProvider) {
}
override fun process(modifiableModelsProvider: IdeModifiableModelsProvider,
module: Module,
rootModel: MavenRootModelAdapter,
mavenModel: MavenProjectsTree,
mavenProject: MavenProject,
changes: MavenProjectChanges,
mavenProjectToModuleName: MutableMap<MavenProject, String>,
postTasks: MutableList<MavenProjectsProcessorTask>) {
if (changes.plugins) {
contributeSourceDirectories(mavenProject, module, rootModel)
}
}
// TODO in theory it should work like this but it doesn't as it couldn't unmark source roots that are not roots anymore.
// I believe this is something should be done by the underlying maven importer implementation or somewhere else in the IDEA
// For now there is a contributeSourceDirectories implementation that deals with the issue
// see https://youtrack.jetbrains.com/issue/IDEA-148280
// override fun collectSourceRoots(mavenProject: MavenProject, result: PairConsumer<String, JpsModuleSourceRootType<*>>) {
// for ((type, dir) in collectSourceDirectories(mavenProject)) {
// val jpsType: JpsModuleSourceRootType<*> = when (type) {
// SourceType.PROD -> JavaSourceRootType.SOURCE
// SourceType.TEST -> JavaSourceRootType.TEST_SOURCE
// }
//
// result.consume(dir, jpsType)
// }
// }
private fun contributeSourceDirectories(mavenProject: MavenProject, module: Module, rootModel: MavenRootModelAdapter) {
val directories = collectSourceDirectories(mavenProject)
val toBeAdded = directories.map { it.second }.toSet()
val state = module.kotlinImporterComponent
for ((type, dir) in directories) {
if (rootModel.getSourceFolder(File(dir)) == null) {
val jpsType: JpsModuleSourceRootType<*> = when (type) {
SourceType.TEST -> JavaSourceRootType.TEST_SOURCE
SourceType.PROD -> JavaSourceRootType.SOURCE
}
rootModel.addSourceFolder(dir, jpsType)
}
}
state.addedSources.filter { it !in toBeAdded }.forEach {
rootModel.unregisterAll(it, true, true)
state.addedSources.remove(it)
}
state.addedSources.addAll(toBeAdded)
}
private fun collectSourceDirectories(mavenProject: MavenProject): List<Pair<SourceType, String>> =
mavenProject.plugins.filter { it.isKotlinPlugin() }.flatMap { plugin ->
plugin.configurationElement.sourceDirectories().map { SourceType.PROD to it } +
plugin.executions.flatMap { execution -> execution.configurationElement.sourceDirectories().map { execution.sourceType() to it } }
}.distinct()
}
private fun MavenPlugin.isKotlinPlugin() = groupId == KotlinPluginGroupId && artifactId == KotlinPluginArtifactId
private fun Element?.sourceDirectories(): List<String> = this?.getChildren(KotlinPluginSourceDirsConfig)?.flatMap { it.children ?: emptyList() }?.map { it.textTrim } ?: emptyList()
private fun MavenPlugin.Execution.sourceType() =
goals.map { if (isTestGoalName(it)) SourceType.TEST else SourceType.PROD }
.distinct()
.singleOrNull() ?: SourceType.PROD
private fun isTestGoalName(goalName: String) = goalName.startsWith("test-")
private enum class SourceType {
PROD, TEST
}
@State(name = "AutoImportedSourceRoots",
storages = arrayOf(
Storage(id = "other", file = StoragePathMacros.MODULE_FILE)
))
class KotlinImporterComponent : PersistentStateComponent<KotlinImporterComponent.State> {
class State(var directories: List<String> = ArrayList())
val addedSources = Collections.synchronizedSet(HashSet<String>())
override fun loadState(state: KotlinImporterComponent.State?) {
addedSources.clear()
if (state != null) {
addedSources.addAll(state.directories)
}
}
override fun getState(): KotlinImporterComponent.State {
return KotlinImporterComponent.State(addedSources.sorted())
}
}
private val Module.kotlinImporterComponent: KotlinImporterComponent
get() = getComponent(KotlinImporterComponent::class.java) ?: throw IllegalStateException("No maven importer state configured")
@@ -0,0 +1,391 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.maven
import org.jetbrains.kotlin.idea.configuration.KotlinImporterComponent
import java.io.File
class KotlinMavenImporterTest : MavenImportingTestCase() {
private val kotlinVersion = "1.0.0-beta-2423"
override fun setUp() {
super.setUp()
repositoryPath = File(myDir, "repo").path
createStdProjectFolders()
}
fun testSimpleKotlinProject() {
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
""")
assertModules("project")
assertImporterStatePresent()
assertSources("project", "src/main/java")
}
fun testWithSpecifiedSourceRoot() {
createProjectSubDir("src/main/kotlin")
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
</build>
""")
assertModules("project")
assertImporterStatePresent()
assertSources("project", "src/main/kotlin")
}
fun testWithCustomSourceDirs() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/main/kotlin</dir>
<dir>src/main/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/test/kotlin</dir>
<dir>src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
assertModules("project")
assertImporterStatePresent()
assertSources("project", "src/main/kotlin", "src/main/kotlin.jvm")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
}
fun testReImportRemoveDir() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/main/kotlin</dir>
<dir>src/main/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/test/kotlin</dir>
<dir>src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
assertModules("project")
assertImporterStatePresent()
assertSources("project", "src/main/kotlin", "src/main/kotlin.jvm")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
// reimport
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/main/kotlin</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/test/kotlin</dir>
<dir>src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
assertSources("project", "src/main/kotlin")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
}
fun testReImportAddDir() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/main/kotlin</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/test/kotlin</dir>
<dir>src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
assertModules("project")
assertImporterStatePresent()
assertSources("project", "src/main/kotlin")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
// reimport
importProject("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>$kotlinVersion</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/main/kotlin</dir>
<dir>src/main/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<dir>src/test/kotlin</dir>
<dir>src/test/kotlin.jvm</dir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
assertSources("project", "src/main/kotlin", "src/main/kotlin.jvm")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
}
private fun assertImporterStatePresent() {
assertNotNull("Kotlin importer component is not present", myTestFixture.module.getComponent(KotlinImporterComponent::class.java))
}
}
@@ -0,0 +1,585 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.maven;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TestDialog;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.util.Consumer;
import com.intellij.util.PathUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.execution.*;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.model.MavenExplicitProfiles;
import org.jetbrains.idea.maven.project.*;
import org.jetbrains.idea.maven.server.MavenServerManager;
import org.jetbrains.jps.model.java.JavaResourceRootType;
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class MavenImportingTestCase extends MavenTestCase {
protected MavenProjectsTree myProjectsTree;
protected MavenProjectsManager myProjectsManager;
private File myGlobalSettingsFile;
@Override
protected void setUp() throws Exception {
VfsRootAccess.allowRootAccess(PathManager.getConfigPath());
super.setUp();
myGlobalSettingsFile =
MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings().generalSettings.getEffectiveGlobalSettingsIoFile();
if (myGlobalSettingsFile != null) {
VfsRootAccess.allowRootAccess(myGlobalSettingsFile.getAbsolutePath());
}
}
@Override
protected void setUpInWriteAction() throws Exception {
super.setUpInWriteAction();
myProjectsManager = MavenProjectsManager.getInstance(myProject);
removeFromLocalRepository("test");
}
@Override
protected void tearDown() throws Exception {
try {
if (myGlobalSettingsFile != null) {
VfsRootAccess.disallowRootAccess(myGlobalSettingsFile.getAbsolutePath());
}
VfsRootAccess.disallowRootAccess(PathManager.getConfigPath());
Messages.setTestDialog(TestDialog.DEFAULT);
removeFromLocalRepository("test");
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory());
}
finally {
super.tearDown();
}
}
protected void assertModules(String... expectedNames) {
Module[] actual = ModuleManager.getInstance(myProject).getModules();
List<String> actualNames = new ArrayList<String>();
for (Module m : actual) {
actualNames.add(m.getName());
}
assertUnorderedElementsAreEqual(actualNames, expectedNames);
}
protected void assertContentRoots(String moduleName, String... expectedRoots) {
List<String> actual = new ArrayList<String>();
for (ContentEntry e : getContentRoots(moduleName)) {
actual.add(e.getUrl());
}
for (int i = 0; i < expectedRoots.length; i++) {
expectedRoots[i] = VfsUtil.pathToUrl(expectedRoots[i]);
}
assertUnorderedPathsAreEqual(actual, Arrays.asList(expectedRoots));
}
protected void assertSources(String moduleName, String... expectedSources) {
doAssertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
}
protected void assertGeneratedSources(String moduleName, String... expectedSources) {
ContentEntry contentRoot = getContentRoot(moduleName);
List<ContentFolder> folders = new ArrayList<ContentFolder>();
for (SourceFolder folder : contentRoot.getSourceFolders(JavaSourceRootType.SOURCE)) {
JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaSourceRootType.SOURCE);
assertNotNull(properties);
if (properties.isForGeneratedSources()) {
folders.add(folder);
}
}
doAssertContentFolders(contentRoot, folders, expectedSources);
}
protected void assertResources(String moduleName, String... expectedSources) {
doAssertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
}
protected void assertTestSources(String moduleName, String... expectedSources) {
doAssertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
}
protected void assertTestResources(String moduleName, String... expectedSources) {
doAssertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
}
protected void assertExcludes(String moduleName, String... expectedExcludes) {
ContentEntry contentRoot = getContentRoot(moduleName);
doAssertContentFolders(contentRoot, Arrays.asList(contentRoot.getExcludeFolders()), expectedExcludes);
}
protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
ContentEntry root = getContentRoot(moduleName, contentRoot);
doAssertContentFolders(root, Arrays.asList(root.getExcludeFolders()), expectedExcudes);
}
private void doAssertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType<?> rootType, String... expected) {
ContentEntry contentRoot = getContentRoot(moduleName);
doAssertContentFolders(contentRoot, contentRoot.getSourceFolders(rootType), expected);
}
private static void doAssertContentFolders(ContentEntry e, final List<? extends ContentFolder> folders, String... expected) {
List<String> actual = new ArrayList<String>();
for (ContentFolder f : folders) {
String rootUrl = e.getUrl();
String folderUrl = f.getUrl();
if (folderUrl.startsWith(rootUrl)) {
int length = rootUrl.length() + 1;
folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
}
actual.add(folderUrl);
}
assertOrderedElementsAreEqual(actual, Arrays.asList(expected));
}
protected void assertModuleOutput(String moduleName, String output, String testOutput) {
CompilerModuleExtension e = getCompilerExtension(moduleName);
assertFalse(e.isCompilerOutputPathInherited());
assertEquals(output, getAbsolutePath(e.getCompilerOutputUrl()));
assertEquals(testOutput, getAbsolutePath(e.getCompilerOutputUrlForTests()));
}
private static String getAbsolutePath(String path) {
path = VfsUtil.urlToPath(path);
path = PathUtil.getCanonicalPath(path);
return FileUtil.toSystemIndependentName(path);
}
protected void assertProjectOutput(String module) {
assertTrue(getCompilerExtension(module).isCompilerOutputPathInherited());
}
protected CompilerModuleExtension getCompilerExtension(String module) {
ModuleRootManager m = getRootManager(module);
return CompilerModuleExtension.getInstance(m.getModule());
}
protected void assertModuleLibDep(String moduleName, String depName) {
assertModuleLibDep(moduleName, depName, null);
}
protected void assertModuleLibDep(String moduleName, String depName, String classesPath) {
assertModuleLibDep(moduleName, depName, classesPath, null, null);
}
protected void assertModuleLibDep(String moduleName, String depName, String classesPath, String sourcePath, String javadocPath) {
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath));
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath));
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPath == null ? null : Collections.singletonList(javadocPath));
}
protected void assertModuleLibDep(String moduleName,
String depName,
List<String> classesPaths,
List<String> sourcePaths,
List<String> javadocPaths) {
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths);
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePaths);
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPaths);
}
private static void assertModuleLibDepPath(LibraryOrderEntry lib, OrderRootType type, List<String> paths) {
if (paths == null) return;
assertUnorderedPathsAreEqual(Arrays.asList(lib.getRootUrls(type)), paths);
// also check the library because it may contain slight different set of urls (e.g. with duplicates)
assertUnorderedPathsAreEqual(Arrays.asList(lib.getLibrary().getUrls(type)), paths);
}
protected void assertModuleLibDepScope(String moduleName, String depName, DependencyScope scope) {
LibraryOrderEntry dep = getModuleLibDep(moduleName, depName);
assertEquals(scope, dep.getScope());
}
private LibraryOrderEntry getModuleLibDep(String moduleName, String depName) {
return getModuleDep(moduleName, depName, LibraryOrderEntry.class);
}
protected void assertModuleLibDeps(String moduleName, String... expectedDeps) {
assertModuleDeps(moduleName, LibraryOrderEntry.class, expectedDeps);
}
protected void assertExportedDeps(String moduleName, String... expectedDeps) {
final List<String> actual = new ArrayList<String>();
getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly().process(new RootPolicy<Object>() {
@Override
public Object visitModuleOrderEntry(ModuleOrderEntry e, Object value) {
actual.add(e.getModuleName());
return null;
}
@Override
public Object visitLibraryOrderEntry(LibraryOrderEntry e, Object value) {
actual.add(e.getLibraryName());
return null;
}
}, null);
assertOrderedElementsAreEqual(actual, expectedDeps);
}
protected void assertModuleModuleDeps(String moduleName, String... expectedDeps) {
assertModuleDeps(moduleName, ModuleOrderEntry.class, expectedDeps);
}
private void assertModuleDeps(String moduleName, Class clazz, String... expectedDeps) {
assertOrderedElementsAreEqual(collectModuleDepsNames(moduleName, clazz), expectedDeps);
}
protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope scope) {
ModuleOrderEntry dep = getModuleModuleDep(moduleName, depName);
assertEquals(scope, dep.getScope());
}
private ModuleOrderEntry getModuleModuleDep(String moduleName, String depName) {
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
}
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
List<String> actual = new ArrayList<String>();
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
if (clazz.isInstance(e)) {
actual.add(e.getPresentableName());
}
}
return actual;
}
private <T> T getModuleDep(String moduleName, String depName, Class<T> clazz) {
T dep = null;
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
dep = (T)e;
}
}
assertNotNull("Dependency not found: " + depName
+ "\namong: " + collectModuleDepsNames(moduleName, clazz),
dep);
return dep;
}
public void assertProjectLibraries(String... expectedNames) {
List<String> actualNames = new ArrayList<String>();
for (Library each : ProjectLibraryTable.getInstance(myProject).getLibraries()) {
String name = each.getName();
actualNames.add(name == null ? "<unnamed>" : name);
}
assertUnorderedElementsAreEqual(actualNames, expectedNames);
}
protected void assertModuleGroupPath(String moduleName, String... expected) {
String[] path = ModuleManager.getInstance(myProject).getModuleGroupPath(getModule(moduleName));
if (expected.length == 0) {
assertNull(path);
}
else {
assertNotNull(path);
assertOrderedElementsAreEqual(Arrays.asList(path), expected);
}
}
protected Module getModule(final String name) {
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
try {
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
assertNotNull("Module " + name + " not found", m);
return m;
}
finally {
accessToken.finish();
}
}
private ContentEntry getContentRoot(String moduleName) {
ContentEntry[] ee = getContentRoots(moduleName);
List<String> roots = new ArrayList<String>();
for (ContentEntry e : ee) {
roots.add(e.getUrl());
}
String message = "Several content roots found: [" + StringUtil.join(roots, ", ") + "]";
assertEquals(message, 1, ee.length);
return ee[0];
}
private ContentEntry getContentRoot(String moduleName, String path) {
for (ContentEntry e : getContentRoots(moduleName)) {
if (e.getUrl().equals(VfsUtil.pathToUrl(path))) return e;
}
throw new AssertionError("content root not found");
}
public ContentEntry[] getContentRoots(String moduleName) {
return getRootManager(moduleName).getContentEntries();
}
private ModuleRootManager getRootManager(String module) {
return ModuleRootManager.getInstance(getModule(module));
}
protected void importProject(@NonNls String xml) throws IOException {
createProjectPom(xml);
importProject();
}
protected void importProject() {
importProjectWithProfiles();
}
protected void importProjectWithProfiles(String... profiles) {
doImportProjects(true, Collections.singletonList(myProjectPom), profiles);
}
protected void importProject(VirtualFile file) {
importProjects(file);
}
protected void importProjects(VirtualFile... files) {
doImportProjects(true, Arrays.asList(files));
}
protected void importProjectWithMaven3(@NonNls String xml) throws IOException {
createProjectPom(xml);
importProjectWithMaven3();
}
protected void importProjectWithMaven3() {
importProjectWithMaven3WithProfiles();
}
protected void importProjectWithMaven3WithProfiles(String... profiles) {
doImportProjects(false, Collections.singletonList(myProjectPom), profiles);
}
private void doImportProjects(boolean useMaven2, final List<VirtualFile> files, String... profiles) {
MavenServerManager.getInstance().setUseMaven2(useMaven2);
initProjectsManager(false);
readProjects(files, profiles);
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
myProjectsManager.waitForResolvingCompletion();
myProjectsManager.scheduleImportInTests(files);
myProjectsManager.importProjects();
}
});
for (MavenProject each : myProjectsTree.getProjects()) {
if (each.hasReadingProblems()) {
System.out.println(each + " has problems: " + each.getProblems());
}
}
}
protected void readProjects(List<VirtualFile> files, String... profiles) {
myProjectsManager.resetManagedFilesAndProfilesInTests(files, new MavenExplicitProfiles(Arrays.asList(profiles)));
waitForReadingCompletion();
}
protected void updateProjectsAndImport(VirtualFile... files) {
readProjects(files);
myProjectsManager.performScheduledImportInTests();
}
protected void initProjectsManager(boolean enableEventHandling) {
myProjectsManager.initForTests();
myProjectsTree = myProjectsManager.getProjectsTreeForTests();
if (enableEventHandling) myProjectsManager.listenForExternalChanges();
}
protected void scheduleResolveAll() {
myProjectsManager.scheduleResolveAllInTests();
}
protected void waitForReadingCompletion() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
myProjectsManager.waitForReadingCompletion();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
protected void readProjects() {
readProjects(myProjectsManager.getProjectsFiles());
}
protected void readProjects(VirtualFile... files) {
List<MavenProject> projects = new ArrayList<MavenProject>();
for (VirtualFile each : files) {
projects.add(myProjectsManager.findProject(each));
}
myProjectsManager.forceUpdateProjects(projects);
waitForReadingCompletion();
}
protected void resolveDependenciesAndImport() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
myProjectsManager.waitForResolvingCompletion();
myProjectsManager.performScheduledImportInTests();
}
});
}
protected void resolveFoldersAndImport() {
myProjectsManager.scheduleFoldersResolveForAllProjects();
myProjectsManager.waitForFoldersResolvingCompletion();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
myProjectsManager.performScheduledImportInTests();
}
});
}
protected void resolvePlugins() {
myProjectsManager.waitForPluginsResolvingCompletion();
}
protected void downloadArtifacts() {
downloadArtifacts(myProjectsManager.getProjects(), null);
}
protected MavenArtifactDownloader.DownloadResult downloadArtifacts(Collection<MavenProject> projects,
List<MavenArtifact> artifacts) {
final MavenArtifactDownloader.DownloadResult[] unresolved = new MavenArtifactDownloader.DownloadResult[1];
AsyncResult<MavenArtifactDownloader.DownloadResult> result = new AsyncResult<MavenArtifactDownloader.DownloadResult>();
result.doWhenDone(new Consumer<MavenArtifactDownloader.DownloadResult>() {
@Override
public void consume(MavenArtifactDownloader.DownloadResult unresolvedArtifacts) {
unresolved[0] = unresolvedArtifacts;
}
});
myProjectsManager.scheduleArtifactsDownloading(projects, artifacts, true, true, result);
myProjectsManager.waitForArtifactsDownloadingCompletion();
return unresolved[0];
}
protected void performPostImportTasks() {
myProjectsManager.waitForPostImportTasksCompletion();
}
protected void executeGoal(String relativePath, String goal) {
VirtualFile dir = myProjectRoot.findFileByRelativePath(relativePath);
MavenRunnerParameters rp = new MavenRunnerParameters(true, dir.getPath(), Arrays.asList(goal), Collections.<String>emptyList());
MavenRunnerSettings rs = new MavenRunnerSettings();
MavenExecutor e = new MavenExternalExecutor(myProject, rp, getMavenGeneralSettings(), rs, new SoutMavenConsole());
e.execute(new EmptyProgressIndicator());
}
protected void removeFromLocalRepository(String relativePath) throws IOException {
FileUtil.delete(new File(getRepositoryPath(), relativePath));
}
protected void setupJdkForModules(String... moduleNames) {
for (String each : moduleNames) {
setupJdkForModule(each);
}
}
protected Sdk setupJdkForModule(final String moduleName) {
final Sdk sdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
return sdk;
}
protected static Sdk createJdk(String versionName) {
return IdeaTestUtil.getMockJdk17(versionName);
}
protected static AtomicInteger configConfirmationForYesAnswer() {
final AtomicInteger counter = new AtomicInteger();
Messages.setTestDialog(new TestDialog() {
@Override
public int show(String message) {
counter.set(counter.get() + 1);
return 0;
}
});
return counter;
}
protected static AtomicInteger configConfirmationForNoAnswer() {
final AtomicInteger counter = new AtomicInteger();
Messages.setTestDialog(new TestDialog() {
@Override
public int show(String message) {
counter.set(counter.get() + 1);
return 1;
}
});
return counter;
}
}
@@ -0,0 +1,617 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.maven;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashSet;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.indices.MavenIndicesManager;
import org.jetbrains.idea.maven.project.*;
import org.jetbrains.idea.maven.utils.MavenProgressIndicator;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.List;
public abstract class MavenTestCase extends UsefulTestCase {
protected static final MavenConsole NULL_MAVEN_CONSOLE = new NullMavenConsole();
// should not be static
protected static MavenProgressIndicator EMPTY_MAVEN_PROCESS = new MavenProgressIndicator(new EmptyProgressIndicator());
private File ourTempDir;
protected IdeaProjectTestFixture myTestFixture;
protected Project myProject;
protected File myDir;
protected VirtualFile myProjectRoot;
protected VirtualFile myProjectPom;
protected List<VirtualFile> myAllPoms = new ArrayList<VirtualFile>();
@Override
protected void setUp() throws Exception {
super.setUp();
ensureTempDirCreated();
myDir = new File(ourTempDir, getTestName(false));
FileUtil.ensureExists(myDir);
setUpFixtures();
myProject = myTestFixture.getProject();
MavenWorkspaceSettingsComponent.getInstance(myProject).loadState(new MavenWorkspaceSettings());
String home = getTestMavenHome();
if (home != null) {
getMavenGeneralSettings().setMavenHome(home);
}
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
restoreSettingsFile();
}
catch (IOException e) {
throw new RuntimeException(e);
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
setUpInWriteAction();
}
catch (Throwable e) {
try {
tearDown();
}
catch (Exception e1) {
e1.printStackTrace();
}
throw new RuntimeException(e);
}
}
});
}
});
}
private void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
ourTempDir = new File(FileUtil.getTempDirectory(), "mavenTests");
FileUtil.delete(ourTempDir);
FileUtil.ensureExists(ourTempDir);
}
protected void setUpFixtures() throws Exception {
myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).getFixture();
myTestFixture.setUp();
}
protected void setUpInWriteAction() throws Exception {
File projectDir = new File(myDir, "project");
projectDir.mkdirs();
myProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir);
}
@Override
protected void tearDown() throws Exception {
try {
myProject = null;
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
tearDownFixtures();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
MavenIndicesManager.getInstance().clear();
}
finally {
super.tearDown();
FileUtil.delete(myDir);
// cannot use reliably the result of the com.intellij.openapi.util.io.FileUtil.delete() method
// because com.intellij.openapi.util.io.FileUtilRt.deleteRecursivelyNIO() does not honor this contract
if (myDir.exists()) {
System.err.println("Cannot delete " + myDir);
//printDirectoryContent(myDir);
myDir.deleteOnExit();
}
resetClassFields(getClass());
}
}
private static void printDirectoryContent(File dir) {
File[] files = dir.listFiles();
if (files == null) return;
for (File file : files) {
System.out.println(file.getAbsolutePath());
if (file.isDirectory()) {
printDirectoryContent(file);
}
}
}
protected void tearDownFixtures() throws Exception {
myTestFixture.tearDown();
myTestFixture = null;
}
private void resetClassFields(final Class<?> aClass) {
if (aClass == null) return;
final Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
final int modifiers = field.getModifiers();
if ((modifiers & Modifier.FINAL) == 0
&& (modifiers & Modifier.STATIC) == 0
&& !field.getType().isPrimitive()) {
field.setAccessible(true);
try {
field.set(this, null);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
if (aClass == MavenTestCase.class) return;
resetClassFields(aClass.getSuperclass());
}
@Override
protected void runTest() throws Throwable {
try {
if (runInWriteAction()) {
new WriteAction() {
@Override
protected void run(@NotNull Result result) throws Throwable {
MavenTestCase.super.runTest();
}
}.executeSilently().throwException();
}
else {
MavenTestCase.super.runTest();
}
}
catch (Exception throwable) {
Throwable each = throwable;
do {
if (each instanceof HeadlessException) {
printIgnoredMessage("Doesn't work in Headless environment");
return;
}
}
while ((each = each.getCause()) != null);
throw throwable;
}
}
@Override
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
runnable.run();
}
protected boolean runInWriteAction() {
return false;
}
protected static String getRoot() {
if (SystemInfo.isWindows) return "c:";
return "";
}
protected static String getEnvVar() {
if (SystemInfo.isWindows) return "TEMP";
else if (SystemInfo.isLinux) return "HOME";
return "TMPDIR";
}
protected MavenGeneralSettings getMavenGeneralSettings() {
return MavenProjectsManager.getInstance(myProject).getGeneralSettings();
}
protected MavenImportingSettings getMavenImporterSettings() {
return MavenProjectsManager.getInstance(myProject).getImportingSettings();
}
protected String getRepositoryPath() {
String path = getRepositoryFile().getPath();
return FileUtil.toSystemIndependentName(path);
}
protected File getRepositoryFile() {
return getMavenGeneralSettings().getEffectiveLocalRepository();
}
protected void setRepositoryPath(String path) {
getMavenGeneralSettings().setLocalRepository(path);
}
protected String getProjectPath() {
return myProjectRoot.getPath();
}
protected String getParentPath() {
return myProjectRoot.getParent().getPath();
}
protected String pathFromBasedir(String relPath) {
return pathFromBasedir(myProjectRoot, relPath);
}
protected static String pathFromBasedir(VirtualFile root, String relPath) {
return FileUtil.toSystemIndependentName(root.getPath() + "/" + relPath);
}
protected VirtualFile updateSettingsXml(String content) throws IOException {
return updateSettingsXmlFully(createSettingsXmlContent(content));
}
protected VirtualFile updateSettingsXmlFully(@NonNls @Language("XML") String content) throws IOException {
File ioFile = new File(myDir, "settings.xml");
ioFile.createNewFile();
VirtualFile f = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
setFileContent(f, content, true);
getMavenGeneralSettings().setUserSettingsFile(f.getPath());
return f;
}
protected void deleteSettingsXml() throws IOException {
new WriteCommandAction.Simple(myProject) {
@Override
protected void run() throws Throwable {
VirtualFile f = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(myDir, "settings.xml"));
if (f != null) f.delete(this);
}
}.execute().throwException();
}
private static String createSettingsXmlContent(String content) {
String mirror = System.getProperty("idea.maven.test.mirror",
// use JB maven proxy server for internal use by default, see details at
// https://confluence.jetbrains.com/display/JBINT/Maven+proxy+server
"http://maven.labs.intellij.net/repo");
return "<settings>" +
content +
"<mirrors>" +
" <mirror>" +
" <id>jb-central-proxy</id>" +
" <url>" + mirror + "</url>" +
" <mirrorOf>external:*</mirrorOf>" +
" </mirror>" +
"</mirrors>" +
"</settings>";
}
protected void restoreSettingsFile() throws IOException {
updateSettingsXml("");
}
protected Module createModule(String name) throws IOException {
return createModule(name, StdModuleTypes.JAVA);
}
protected Module createModule(final String name, final ModuleType type) throws IOException {
return new WriteCommandAction<Module>(myProject) {
@Override
protected void run(@NotNull Result<Module> moduleResult) throws Throwable {
VirtualFile f = createProjectSubFile(name + "/" + name + ".iml");
Module module = ModuleManager.getInstance(myProject).newModule(f.getPath(), type.getId());
PsiTestUtil.addContentRoot(module, f.getParent());
moduleResult.setResult(module);
}
}.execute().getResultObject();
}
protected VirtualFile createProjectPom(@NonNls String xml) throws IOException {
return myProjectPom = createPomFile(myProjectRoot, xml);
}
protected VirtualFile createModulePom(String relativePath, String xml) throws IOException {
return createPomFile(createProjectSubDir(relativePath), xml);
}
protected VirtualFile createPomFile(final VirtualFile dir, String xml) throws IOException {
VirtualFile f = dir.findChild("pom.xml");
if (f == null) {
f = new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
VirtualFile res = dir.createChildData(null, "pom.xml");
result.setResult(res);
}
}.execute().getResultObject();
myAllPoms.add(f);
}
setFileContent(f, createPomXml(xml), true);
return f;
}
@NonNls @Language(value="XML")
public static String createPomXml(@NonNls @Language(value="XML", prefix="<xml>", suffix="</xml>") String xml) {
return "<?xml version=\"1.0\"?>" +
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">" +
" <modelVersion>4.0.0</modelVersion>" +
xml +
"</project>";
}
protected VirtualFile createProfilesXmlOldStyle(String xml) throws IOException {
return createProfilesFile(myProjectRoot, xml, true);
}
protected VirtualFile createProfilesXmlOldStyle(String relativePath, String xml) throws IOException {
return createProfilesFile(createProjectSubDir(relativePath), xml, true);
}
protected VirtualFile createProfilesXml(String xml) throws IOException {
return createProfilesFile(myProjectRoot, xml, false);
}
protected VirtualFile createProfilesXml(String relativePath, String xml) throws IOException {
return createProfilesFile(createProjectSubDir(relativePath), xml, false);
}
private static VirtualFile createProfilesFile(VirtualFile dir, String xml, boolean oldStyle) throws IOException {
return createProfilesFile(dir, createValidProfiles(xml, oldStyle));
}
protected VirtualFile createFullProfilesXml(String content) throws IOException {
return createProfilesFile(myProjectRoot, content);
}
protected VirtualFile createFullProfilesXml(String relativePath, String content) throws IOException {
return createProfilesFile(createProjectSubDir(relativePath), content);
}
private static VirtualFile createProfilesFile(final VirtualFile dir, String content) throws IOException {
VirtualFile f = dir.findChild("profiles.xml");
if (f == null) {
f = new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
VirtualFile res = dir.createChildData(null, "profiles.xml");
result.setResult(res);
}
}.execute().getResultObject();
}
setFileContent(f, content, true);
return f;
}
@Language("XML")
private static String createValidProfiles(String xml, boolean oldStyle) {
if (oldStyle) {
return "<?xml version=\"1.0\"?>" +
"<profiles>" +
xml +
"</profiles>";
}
return "<?xml version=\"1.0\"?>" +
"<profilesXml>" +
"<profiles>" +
xml +
"</profiles>" +
"</profilesXml>";
}
protected void deleteProfilesXml() throws IOException {
new WriteCommandAction.Simple(myProject) {
@Override
protected void run() throws Throwable {
VirtualFile f = myProjectRoot.findChild("profiles.xml");
if (f != null) f.delete(this);
}
}.execute().throwException();
}
protected void createStdProjectFolders() {
createProjectSubDirs("src/main/java",
"src/main/resources",
"src/test/java",
"src/test/resources");
}
protected void createProjectSubDirs(String... relativePaths) {
for (String path : relativePaths) {
createProjectSubDir(path);
}
}
protected VirtualFile createProjectSubDir(String relativePath) {
File f = new File(getProjectPath(), relativePath);
f.mkdirs();
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
File f = new File(getProjectPath(), relativePath);
f.getParentFile().mkdirs();
f.createNewFile();
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
VirtualFile file = createProjectSubFile(relativePath);
setFileContent(file, content, false);
return file;
}
private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
if (advanceStamps) {
file.setBinaryContent(content.getBytes(), -1, file.getTimeStamp() + 4000);
}
else {
file.setBinaryContent(content.getBytes(), file.getModificationStamp(), file.getTimeStamp());
}
}
}.execute().getResultObject();
}
protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, Collection<T> expected) {
assertOrderedElementsAreEqual(actual, expected.toArray());
}
protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, Collection<T> expected) {
assertEquals(new HashSet<T>(expected), new HashSet<T>(actual));
}
protected static void assertUnorderedPathsAreEqual(Collection<String> actual, Collection<String> expected) {
assertEquals(new SetWithToString<String>(new THashSet<String>(expected, FileUtil.PATH_HASHING_STRATEGY)),
new SetWithToString<String>(new THashSet<String>(actual, FileUtil.PATH_HASHING_STRATEGY)));
}
protected static <T> void assertUnorderedElementsAreEqual(T[] actual, T... expected) {
assertUnorderedElementsAreEqual(Arrays.asList(actual), expected);
}
protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, T... expected) {
assertUnorderedElementsAreEqual(actual, Arrays.asList(expected));
}
protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, T... expected) {
String s = "\nexpected: " + Arrays.asList(expected) + "\nactual: " + new ArrayList<U>(actual);
assertEquals(s, expected.length, actual.size());
List<U> actualList = new ArrayList<U>(actual);
for (int i = 0; i < expected.length; i++) {
T expectedElement = expected[i];
U actualElement = actualList.get(i);
assertEquals(s, expectedElement, actualElement);
}
}
protected static <T> void assertContain(List<? extends T> actual, T... expected) {
List<T> expectedList = Arrays.asList(expected);
assertTrue("expected: " + expectedList + "\n" + "actual: " + actual.toString(), actual.containsAll(expectedList));
}
protected static <T> void assertDoNotContain(List<T> actual, T... expected) {
List<T> actualCopy = new ArrayList<T>(actual);
actualCopy.removeAll(Arrays.asList(expected));
assertEquals(actual.toString(), actualCopy.size(), actual.size());
}
protected boolean ignore() {
printIgnoredMessage(null);
return true;
}
protected boolean hasMavenInstallation() {
boolean result = getTestMavenHome() != null;
if (!result) printIgnoredMessage("Maven installation not found");
return result;
}
private void printIgnoredMessage(String message) {
String toPrint = "Ignored";
if (message != null) {
toPrint += ", because " + message;
}
toPrint += ": " + getClass().getSimpleName() + "." + getName();
System.out.println(toPrint);
}
private static String getTestMavenHome() {
return System.getProperty("idea.maven.test.home");
}
private static class SetWithToString<T> extends AbstractSet<T> {
private final Set<T> myDelegate;
public SetWithToString(@NotNull Set<T> delegate) {
myDelegate = delegate;
}
@Override
public int size() {
return myDelegate.size();
}
@Override
public boolean contains(Object o) {
return myDelegate.contains(o);
}
@NotNull
@Override
public Iterator<T> iterator() {
return myDelegate.iterator();
}
@Override
public boolean containsAll(Collection<?> c) {
return myDelegate.containsAll(c);
}
@Override
public boolean equals(Object o) {
return myDelegate.equals(o);
}
@Override
public int hashCode() {
return myDelegate.hashCode();
}
}
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.maven;
import com.intellij.execution.process.ProcessHandler;
import org.jetbrains.idea.maven.execution.MavenExecutionOptions;
import org.jetbrains.idea.maven.project.MavenConsole;
public class NullMavenConsole extends MavenConsole {
public NullMavenConsole() {
super(MavenExecutionOptions.LoggingLevel.DISABLED, false);
}
@Override
public boolean canPause() {
return false;
}
@Override
public boolean isOutputPaused() {
return false;
}
@Override
public void setOutputPaused(boolean outputPaused) {
}
@Override
public void attachToProcess(ProcessHandler processHandler) {
}
@Override
protected void doPrint(String text, MavenConsole.OutputType type) {
}
}