Maven: convert to Kotlin

This commit is contained in:
Sergey Mashkov
2016-04-04 15:27:57 +03:00
parent 78d0f83f71
commit 072ec26452
8 changed files with 339 additions and 403 deletions
@@ -1,64 +0,0 @@
/*
* Copyright 2010-2016 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.configuration;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtilsKt;
import org.jetbrains.kotlin.idea.maven.PomFile;
import org.jetbrains.kotlin.resolve.TargetPlatform;
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform;
public class KotlinJavaMavenConfigurator extends KotlinMavenConfigurator {
private static final String NAME = "maven";
public static final String STD_LIB_ID = "kotlin-stdlib";
public static final String TEST_LIB_ID = "kotlin-test";
private static final String PRESENTABLE_TEXT = "Maven";
public KotlinJavaMavenConfigurator() {
super(STD_LIB_ID, TEST_LIB_ID, false, NAME, PRESENTABLE_TEXT);
}
@Override
protected boolean isKotlinModule(@NotNull Module module) {
return ConfigureKotlinInProjectUtilsKt.hasKotlinJvmRuntimeInScope(module);
}
@Override
protected boolean isRelevantGoal(@NotNull String goalName) {
return goalName.equals(PomFile.KotlinGoals.INSTANCE.getCompile());
}
@Override
protected void createExecutions(@NotNull PomFile pomFile, @NotNull MavenDomPlugin kotlinPlugin, @NotNull Module module) {
createExecution(pomFile, kotlinPlugin, module, false);
createExecution(pomFile, kotlinPlugin, module, true);
}
@NotNull
@Override
protected String getGoal(boolean isTest) {
return isTest ? PomFile.KotlinGoals.INSTANCE.getTestCompile() : PomFile.KotlinGoals.INSTANCE.getCompile();
}
@NotNull
@Override
public TargetPlatform getTargetPlatform() {
return JvmPlatform.INSTANCE;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2016 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.configuration
import com.intellij.openapi.module.Module
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin
import org.jetbrains.kotlin.idea.configuration.*
import org.jetbrains.kotlin.idea.maven.PomFile
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
class KotlinJavaMavenConfigurator : KotlinMavenConfigurator(KotlinJavaMavenConfigurator.STD_LIB_ID, KotlinJavaMavenConfigurator.TEST_LIB_ID, false, KotlinJavaMavenConfigurator.NAME, KotlinJavaMavenConfigurator.PRESENTABLE_TEXT) {
override fun isKotlinModule(module: Module): Boolean {
return hasKotlinRuntimeInScope(module)
}
override fun isRelevantGoal(goalName: String): Boolean {
return goalName == PomFile.KotlinGoals.Compile
}
override fun createExecutions(pomFile: PomFile, kotlinPlugin: MavenDomPlugin, module: Module) {
createExecution(pomFile, kotlinPlugin, module, false)
createExecution(pomFile, kotlinPlugin, module, true)
}
override fun getGoal(isTest: Boolean): String {
return if (isTest) PomFile.KotlinGoals.TestCompile else PomFile.KotlinGoals.Compile
}
override fun getTargetPlatform(): TargetPlatform {
return JvmPlatform
}
companion object {
private val NAME = "maven"
val STD_LIB_ID = "kotlin-stdlib"
val TEST_LIB_ID = "kotlin-test"
private val PRESENTABLE_TEXT = "Maven"
}
}
@@ -1,71 +0,0 @@
/*
* Copyright 2010-2016 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.configuration;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
import org.jetbrains.kotlin.idea.maven.PomFile;
import org.jetbrains.kotlin.js.resolve.JsPlatform;
import org.jetbrains.kotlin.resolve.TargetPlatform;
public class KotlinJavascriptMavenConfigurator extends KotlinMavenConfigurator {
private static final String NAME = "js maven";
public static final String STD_LIB_ID = "kotlin-js-library";
private static final String JS_GOAL = "js";
private static final String JS_TEST_GOAL = "test-js";
private static final String JS_EXECUTION_ID = "js";
private static final String PRESENTABLE_TEXT = "JavaScript Maven - experimental";
public KotlinJavascriptMavenConfigurator() {
super(STD_LIB_ID, null, false, NAME, PRESENTABLE_TEXT);
}
@Override
protected boolean isKotlinModule(@NotNull Module module) {
return ConfigureKotlinInProjectUtilsKt.hasKotlinJsRuntimeInScope(module);
}
@Override
protected boolean isRelevantGoal(@NotNull String goalName) {
return goalName.equals(PomFile.KotlinGoals.INSTANCE.getJs());
}
@Override
protected void createExecutions(@NotNull PomFile pomFile, @NotNull MavenDomPlugin kotlinPlugin, @NotNull Module module) {
createExecution(pomFile, kotlinPlugin, module, false);
createExecution(pomFile, kotlinPlugin, module, true);
}
@NotNull
@Override
protected String getExecutionId(boolean isTest) {
return JS_EXECUTION_ID + (isTest ? "-test" : "");
}
@NotNull
@Override
protected String getGoal(boolean isTest) {
return isTest ? JS_TEST_GOAL : JS_GOAL;
}
@NotNull
@Override
public TargetPlatform getTargetPlatform() {
return JsPlatform.INSTANCE;
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2016 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.configuration
import com.intellij.openapi.module.Module
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin
import org.jetbrains.kotlin.idea.maven.PomFile
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform
class KotlinJavascriptMavenConfigurator : KotlinMavenConfigurator(KotlinJavascriptMavenConfigurator.STD_LIB_ID, null, false, KotlinJavascriptMavenConfigurator.NAME, KotlinJavascriptMavenConfigurator.PRESENTABLE_TEXT) {
override fun isKotlinModule(module: Module): Boolean {
return ProjectStructureUtil.isJsKotlinModule(module)
}
override fun isRelevantGoal(goalName: String): Boolean {
return goalName == PomFile.KotlinGoals.Js
}
override fun createExecutions(pomFile: PomFile, kotlinPlugin: MavenDomPlugin, module: Module) {
createExecution(pomFile, kotlinPlugin, module, false)
createExecution(pomFile, kotlinPlugin, module, true)
}
override fun getExecutionId(isTest: Boolean): String {
return JS_EXECUTION_ID + if (isTest) "-test" else ""
}
override fun getGoal(isTest: Boolean): String {
return if (isTest) JS_TEST_GOAL else JS_GOAL
}
override fun getTargetPlatform(): TargetPlatform {
return JsPlatform
}
companion object {
private val NAME = "js maven"
val STD_LIB_ID = "kotlin-js-library"
private val JS_GOAL = "js"
private val JS_TEST_GOAL = "test-js"
private val JS_EXECUTION_ID = "js"
private val PRESENTABLE_TEXT = "JavaScript Maven - experimental"
}
}
@@ -1,261 +0,0 @@
/*
* Copyright 2010-2016 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.configuration;
import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.ide.actions.OpenFileAction;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.WritingAccessProvider;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.model.MavenPlugin;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.utils.MavenArtifactScope;
import org.jetbrains.kotlin.idea.KotlinPluginUtil;
import org.jetbrains.kotlin.idea.configuration.*;
import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion;
import org.jetbrains.kotlin.idea.maven.MavenModulesRelationshipKt;
import org.jetbrains.kotlin.idea.maven.PomFile;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public abstract class KotlinMavenConfigurator implements KotlinProjectConfigurator {
public static final String NAME = "maven";
public static final String GROUP_ID = "org.jetbrains.kotlin";
public static final String MAVEN_PLUGIN_ID = "kotlin-maven-plugin";
private static final String KOTLIN_VERSION_PROPERTY = "kotlin.version";
private static final String TEST_COMPILE_EXECUTION_ID = "test-compile";
private static final String COMPILE_EXECUTION_ID = "compile";
private final String stdlibArtifactId;
private final String testArtifactId;
private final boolean addJunit;
private final String name;
private final String presentableText;
protected KotlinMavenConfigurator(@NotNull String stdlibArtifactId, @Nullable String testArtifactId, boolean addJunit, @NotNull String name, @NotNull String presentableText) {
this.stdlibArtifactId = stdlibArtifactId;
this.testArtifactId = testArtifactId;
this.addJunit = addJunit;
this.name = name;
this.presentableText = presentableText;
}
@Override
public boolean isApplicable(@NotNull Module module) {
return KotlinPluginUtil.isMavenModule(module);
}
@NotNull
@Override
public String getPresentableText() {
return presentableText;
}
@NotNull
@Override
public String getName() {
return name;
}
@Override
public boolean isConfigured(@NotNull Module module) {
if (!isKotlinModule(module)) {
return false;
}
PsiFile psi = findModulePomFile(module);
if (psi == null
|| !psi.isValid()
|| !(psi instanceof XmlFile)
|| psi.getVirtualFile() == null
|| MavenDomUtil.getMavenDomProjectModel(module.getProject(), psi.getVirtualFile()) == null) {
return false;
}
MavenProject mavenProject = MavenProjectsManager.getInstance(module.getProject()).findProject(module);
if (mavenProject == null) {
return false;
}
MavenPlugin plugin = mavenProject.findPlugin(GROUP_ID, MAVEN_PLUGIN_ID);
if (plugin == null) {
return false;
}
if (plugin.getExecutions() != null) {
for (MavenPlugin.Execution execution : plugin.getExecutions()) {
if (execution.getGoals() != null) {
for (String goal : execution.getGoals()) {
if (goal != null && isRelevantGoal(goal)) {
return true;
}
}
}
}
}
return false;
}
@Override
public void configure(@NotNull Project project, Collection<Module> excludeModules) {
ConfigureDialogWithModulesAndVersion dialog =
new ConfigureDialogWithModulesAndVersion(project, this, excludeModules);
dialog.show();
if (!dialog.isOK()) return;
NotificationMessageCollector collector = NotificationMessageCollectorKt.createConfigureKotlinNotificationCollector(project);
for (Module module : MavenModulesRelationshipKt.excludeMavenChildrenModules(project, dialog.getModulesToConfigure())) {
PsiFile file = findModulePomFile(module);
if (file != null && canConfigureFile(file)) {
changePomFile(module, file, dialog.getKotlinVersion(), collector);
OpenFileAction.openFile(file.getVirtualFile(), project);
}
else {
showErrorMessage(project, "Cannot find pom.xml for module " + module.getName());
}
}
collector.showNotification();
}
protected abstract boolean isKotlinModule(@NotNull Module module);
protected abstract boolean isRelevantGoal(@NotNull String goalName);
protected abstract void createExecutions(@NotNull PomFile pomFile, @NotNull MavenDomPlugin kotlinPlugin, @NotNull Module module);
@NotNull
protected abstract String getGoal(boolean isTest);
@NotNull
protected String getExecutionId(boolean isTest) {
return isTest ? TEST_COMPILE_EXECUTION_ID : COMPILE_EXECUTION_ID;
}
protected void changePomFile(
@NotNull final Module module,
final @NotNull PsiFile file,
@NotNull final String version,
@NotNull NotificationMessageCollector collector
) {
VirtualFile virtualFile = file.getVirtualFile();
assert virtualFile != null : "Virtual file should exists for psi file " + file.getName();
MavenDomProjectModel domModel = MavenDomUtil.getMavenDomProjectModel(module.getProject(), virtualFile);
if (domModel == null) {
showErrorMessage(module.getProject(), null);
return;
}
new WriteCommandAction(file.getProject()) {
@Override
protected void run(@NotNull Result result) {
PomFile pom = new PomFile((XmlFile) file);
pom.addProperty(KOTLIN_VERSION_PROPERTY, version);
pom.addDependency(new MavenId(GROUP_ID, stdlibArtifactId, "${" + KOTLIN_VERSION_PROPERTY + "}"), MavenArtifactScope.COMPILE, null, false, null);
if (testArtifactId != null) {
pom.addDependency(new MavenId(GROUP_ID, testArtifactId, "${" + KOTLIN_VERSION_PROPERTY + "}"), MavenArtifactScope.TEST, null, false, null);
}
if (addJunit) {
pom.addDependency(new MavenId("junit", "junit", "4.12"), MavenArtifactScope.TEST, null, false, null);
}
if (isSnapshot(version)) {
pom.addLibraryRepository(ConfigureKotlinInProjectUtilsKt.SNAPSHOT_REPOSITORY, true, false);
pom.addPluginRepository(ConfigureKotlinInProjectUtilsKt.SNAPSHOT_REPOSITORY, true, false);
}
if (ConfigureKotlinInProjectUtilsKt.isEap(version)) {
pom.addLibraryRepository(ConfigureKotlinInProjectUtilsKt.EAP_REPOSITORY, true, false);
pom.addPluginRepository(ConfigureKotlinInProjectUtilsKt.EAP_REPOSITORY, true, false);
}
MavenDomPlugin plugin = pom.addPlugin(new MavenId(GROUP_ID, MAVEN_PLUGIN_ID, "${" + KOTLIN_VERSION_PROPERTY + "}"));
createExecutions(pom, plugin, module);
CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file);
}
}.execute();
collector.addMessage(virtualFile.getPath() + " was modified");
}
protected void createExecution(
@NotNull PomFile pomFile,
@NotNull MavenDomPlugin kotlinPlugin,
@NotNull Module module,
boolean isTest
) {
pomFile.addKotlinExecution(module, kotlinPlugin, getExecutionId(isTest), PomFile.Companion.getPhase(hasJavaFiles(module), isTest), isTest,
Collections.singletonList(getGoal(isTest)));
}
private static boolean hasJavaFiles(@NotNull Module module) {
return !FileTypeIndex.getFiles(JavaFileType.INSTANCE, GlobalSearchScope.moduleScope(module)).isEmpty();
}
@Nullable
private static PsiFile findModulePomFile(@NotNull Module module) {
List<VirtualFile> files = MavenProjectsManager.getInstance(module.getProject()).getProjectsFiles();
for (VirtualFile file : files) {
Module fileModule = ModuleUtilCore.findModuleForFile(file, module.getProject());
if (!module.equals(fileModule)) continue;
PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(file);
if (psiFile == null) continue;
if (!MavenDomUtil.isProjectFile(psiFile)) continue;
return psiFile;
}
return null;
}
private static boolean isSnapshot(@NotNull String version) {
return version.contains("SNAPSHOT");
}
private static boolean canConfigureFile(@NotNull PsiFile file) {
return WritingAccessProvider.isPotentiallyWritable(file.getVirtualFile(), null);
}
private static void showErrorMessage(@NotNull Project project, @Nullable String message) {
Messages.showErrorDialog(project,
"<html>Couldn't configure kotlin-maven plugin automatically.<br/>" +
(message != null ? message : "") +
"See manual installation instructions <a href=\"http://confluence.jetbrains.com/display/Kotlin/Kotlin+Build+Tools#KotlinBuildTools-Maven\">here</a></html>",
"Configure Kotlin-Maven Plugin");
}
}
@@ -0,0 +1,217 @@
/*
* Copyright 2010-2016 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.configuration
import com.intellij.codeInsight.CodeInsightUtilCore
import com.intellij.ide.actions.OpenFileAction
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.vfs.WritingAccessProvider
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.search.FileTypeIndex
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.xml.XmlFile
import org.jetbrains.idea.maven.dom.MavenDomUtil
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin
import org.jetbrains.idea.maven.model.MavenId
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.idea.maven.utils.MavenArtifactScope
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator
import org.jetbrains.kotlin.idea.configuration.NotificationMessageCollector
import org.jetbrains.kotlin.idea.configuration.createConfigureKotlinNotificationCollector
import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion
import org.jetbrains.kotlin.idea.maven.PomFile
import org.jetbrains.kotlin.idea.maven.excludeMavenChildrenModules
abstract class KotlinMavenConfigurator protected constructor(private val stdlibArtifactId: String, private val testArtifactId: String?, private val addJunit: Boolean, private val name: String, private val presentableText: String) : KotlinProjectConfigurator {
override fun isApplicable(module: Module): Boolean {
return KotlinPluginUtil.isMavenModule(module)
}
override fun getPresentableText(): String {
return presentableText
}
override fun getName(): String {
return name
}
override fun isConfigured(module: Module): Boolean {
if (!isKotlinModule(module)) {
return false
}
val psi = findModulePomFile(module)
if (psi == null
|| !psi.isValid
|| psi !is XmlFile
|| psi.virtualFile == null
|| MavenDomUtil.getMavenDomProjectModel(module.project, psi.virtualFile) == null) {
return false
}
val mavenProject = MavenProjectsManager.getInstance(module.project).findProject(module) ?: return false
val plugin = mavenProject.findPlugin(GROUP_ID, MAVEN_PLUGIN_ID) ?: return false
if (plugin.executions != null) {
for (execution in plugin.executions) {
if (execution.goals != null) {
for (goal in execution.goals) {
if (goal != null && isRelevantGoal(goal)) {
return true
}
}
}
}
}
return false
}
override fun configure(project: Project, excludeModules: Collection<Module>) {
val dialog = ConfigureDialogWithModulesAndVersion(project, this, excludeModules)
dialog.show()
if (!dialog.isOK) return
val collector = createConfigureKotlinNotificationCollector(project)
for (module in excludeMavenChildrenModules(project, dialog.modulesToConfigure)) {
val file = findModulePomFile(module)
if (file != null && canConfigureFile(file)) {
changePomFile(module, file, dialog.kotlinVersion, collector)
OpenFileAction.openFile(file.virtualFile, project)
}
else {
showErrorMessage(project, "Cannot find pom.xml for module " + module.name)
}
}
collector.showNotification()
}
protected abstract fun isKotlinModule(module: Module): Boolean
protected abstract fun isRelevantGoal(goalName: String): Boolean
protected abstract fun createExecutions(pomFile: PomFile, kotlinPlugin: MavenDomPlugin, module: Module)
protected abstract fun getGoal(isTest: Boolean): String
protected open fun getExecutionId(isTest: Boolean): String {
return if (isTest) TEST_COMPILE_EXECUTION_ID else COMPILE_EXECUTION_ID
}
fun changePomFile(
module: Module,
file: PsiFile,
version: String,
collector: NotificationMessageCollector) {
val virtualFile = file.virtualFile ?: error("Virtual file should exists for psi file " + file.name)
val domModel = MavenDomUtil.getMavenDomProjectModel(module.project, virtualFile)
if (domModel == null) {
showErrorMessage(module.project, null)
return
}
WriteCommandAction.runWriteCommandAction(module.project) {
val pom = PomFile(file as XmlFile)
pom.addProperty(KOTLIN_VERSION_PROPERTY, version)
pom.addDependency(MavenId(GROUP_ID, stdlibArtifactId, "\${$KOTLIN_VERSION_PROPERTY}"), MavenArtifactScope.COMPILE, null, false, null)
if (testArtifactId != null) {
pom.addDependency(MavenId(GROUP_ID, testArtifactId, "\${$KOTLIN_VERSION_PROPERTY}"), MavenArtifactScope.TEST, null, false, null)
}
if (addJunit) {
pom.addDependency(MavenId("junit", "junit", "4.12"), MavenArtifactScope.TEST, null, false, null)
}
if (isSnapshot(version)) {
pom.addLibraryRepository(SNAPSHOT_REPOSITORY_ID, SONATYPE_OSS_REPOSITORY_NAME, SONATYPE_OSS_REPOSITORY_URL, true, false)
pom.addPluginRepository(SNAPSHOT_REPOSITORY_ID, SONATYPE_OSS_REPOSITORY_NAME, SONATYPE_OSS_REPOSITORY_URL, true, false)
}
val plugin = pom.addPlugin(MavenId(GROUP_ID, MAVEN_PLUGIN_ID, "\${$KOTLIN_VERSION_PROPERTY}"))
createExecutions(pom, plugin, module)
CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement<PsiFile>(file)
}
collector.addMessage(virtualFile.path + " was modified")
}
protected fun createExecution(
pomFile: PomFile,
kotlinPlugin: MavenDomPlugin,
module: Module,
isTest: Boolean) {
pomFile.addKotlinExecution(module, kotlinPlugin, getExecutionId(isTest), PomFile.getPhase(hasJavaFiles(module), isTest), isTest,
listOf(getGoal(isTest)))
}
companion object {
val NAME = "maven"
val GROUP_ID = "org.jetbrains.kotlin"
val MAVEN_PLUGIN_ID = "kotlin-maven-plugin"
private val KOTLIN_VERSION_PROPERTY = "kotlin.version"
private val SNAPSHOT_REPOSITORY_ID = "sonatype.oss.snapshots"
private val SONATYPE_OSS_REPOSITORY_NAME = "Sonatype OSS Snapshot Repository"
private val SONATYPE_OSS_REPOSITORY_URL = "http://oss.sonatype.org/content/repositories/snapshots"
private val TEST_COMPILE_EXECUTION_ID = "test-compile"
private val COMPILE_EXECUTION_ID = "compile"
private fun hasJavaFiles(module: Module): Boolean {
return !FileTypeIndex.getFiles(JavaFileType.INSTANCE, GlobalSearchScope.moduleScope(module)).isEmpty()
}
private fun findModulePomFile(module: Module): PsiFile? {
val files = MavenProjectsManager.getInstance(module.project).projectsFiles
for (file in files) {
val fileModule = ModuleUtilCore.findModuleForFile(file, module.project)
if (module != fileModule) continue
val psiFile = PsiManager.getInstance(module.project).findFile(file) ?: continue
if (!MavenDomUtil.isProjectFile(psiFile)) continue
return psiFile
}
return null
}
private fun isSnapshot(version: String): Boolean {
return version.contains("SNAPSHOT")
}
private fun canConfigureFile(file: PsiFile): Boolean {
return WritingAccessProvider.isPotentiallyWritable(file.virtualFile, null)
}
private fun showErrorMessage(project: Project, message: String?) {
Messages.showErrorDialog(project,
"<html>Couldn't configure kotlin-maven plugin automatically.<br/>" +
(message ?: "") +
"See manual installation instructions <a href=\"http://confluence.jetbrains.com/display/Kotlin/Kotlin+Build+Tools#KotlinBuildTools-Maven\">here</a></html>",
"Configure Kotlin-Maven Plugin")
}
}
}
@@ -36,7 +36,6 @@ import org.jetbrains.idea.maven.model.MavenId
import org.jetbrains.idea.maven.model.MavenPlugin
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.idea.maven.utils.MavenArtifactScope
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.maven.PomFile
import org.jetbrains.kotlin.idea.maven.configuration.KotlinJavaMavenConfigurator
import org.jetbrains.kotlin.idea.maven.configuration.KotlinJavascriptMavenConfigurator
@@ -99,8 +98,8 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
}
}
val stdlibDependencies = mavenProject.findDependencies(KotlinJavaMavenConfigurator.GROUP_ID, KotlinJavaMavenConfigurator.STD_LIB_ID)
val jsDependencies = mavenProject.findDependencies(KotlinJavaMavenConfigurator.GROUP_ID, KotlinJavascriptMavenConfigurator.STD_LIB_ID)
val stdlibDependencies = mavenProject.findDependencies(KotlinMavenConfigurator.GROUP_ID, KotlinJavaMavenConfigurator.STD_LIB_ID)
val jsDependencies = mavenProject.findDependencies(KotlinMavenConfigurator.GROUP_ID, KotlinJavascriptMavenConfigurator.STD_LIB_ID)
if (hasJvmExecution && stdlibDependencies.isEmpty()) {
holder.createProblem(kotlinPlugin.artifactId.createStableCopy(),
@@ -117,7 +116,7 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
}
}
val stdlibDependencies = pom.findDependencies(MavenId(KotlinJavaMavenConfigurator.GROUP_ID, KotlinJavaMavenConfigurator.STD_LIB_ID, null))
val stdlibDependencies = pom.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, KotlinJavaMavenConfigurator.STD_LIB_ID, null))
if (!hasJvmExecution && stdlibDependencies.isNotEmpty()) {
stdlibDependencies.forEach { dep ->
holder.createProblem(dep.artifactId.createStableCopy(),
@@ -127,7 +126,7 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
}
}
val stdlibJsDependencies = pom.findDependencies(MavenId(KotlinJavaMavenConfigurator.GROUP_ID, KotlinJavascriptMavenConfigurator.STD_LIB_ID, null))
val stdlibJsDependencies = pom.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, KotlinJavascriptMavenConfigurator.STD_LIB_ID, null))
if (!hasJsExecution && stdlibJsDependencies.isNotEmpty()) {
stdlibJsDependencies.forEach { dep ->
holder.createProblem(dep.artifactId.createStableCopy(),
@@ -175,7 +174,7 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val file = PomFile(pomFile)
file.addDependency(MavenId(KotlinJavaMavenConfigurator.GROUP_ID, id, version), MavenArtifactScope.COMPILE)
file.addDependency(MavenId(KotlinMavenConfigurator.GROUP_ID, id, version), MavenArtifactScope.COMPILE)
}
}
@@ -51,7 +51,7 @@ class SameVersionInspection : DomElementsInspection<MavenDomProjectModel>(MavenD
"Plugin version (${plugin.version}) is not the same as library version (${stdlibVersion.joinToString(",", "", "")})")
}
pomFile.findDependencies(MavenId(KotlinJavaMavenConfigurator.GROUP_ID, KotlinJavaMavenConfigurator.STD_LIB_ID, null))
pomFile.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, KotlinJavaMavenConfigurator.STD_LIB_ID, null))
.filter { it.version.stringValue != pluginVersion }
.forEach { dependency ->
holder.createProblem(dependency.version, HighlightSeverity.WARNING, "Plugin version ($pluginVersion) is not the same as library version (${dependency.version})")