From 3a973973ceceabcaf12f53a9f0235f6ad9f7aacf Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 20 Sep 2018 18:25:47 +0300 Subject: [PATCH] MPP: Create android source roots automatically when requested #KT-26764 Fixed --- ...KotlinAndroidGradleMPPModuleDataService.kt | 41 ++++++++++++++++-- ...inAndroidGradleMPPModuleDataService.kt.173 | 42 +++++++++++++++++-- ...inAndroidGradleMPPModuleDataService.kt.181 | 41 ++++++++++++++++-- ...nAndroidGradleMPPModuleDataService.kt.as31 | 41 ++++++++++++++++-- ...nAndroidGradleMPPModuleDataService.kt.as32 | 41 ++++++++++++++++-- 5 files changed, 191 insertions(+), 15 deletions(-) diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt index 2a3f1a8edad..a5e88fda92f 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt @@ -8,15 +8,20 @@ package org.jetbrains.kotlin.android.configure import com.android.tools.idea.gradle.project.model.AndroidModuleModel import com.android.tools.idea.gradle.util.ContentEntries.findParentContentEntry import com.android.tools.idea.io.FilePaths +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager import com.intellij.openapi.externalSystem.model.DataNode import com.intellij.openapi.externalSystem.model.ProjectKeys import com.intellij.openapi.externalSystem.model.project.ModuleData import com.intellij.openapi.externalSystem.model.project.ProjectData import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService +import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.vfs.VfsUtil import com.intellij.util.containers.stream import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType @@ -28,10 +33,25 @@ import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService import org.jetbrains.kotlin.idea.configuration.kotlinAndroidSourceSets import org.jetbrains.kotlin.idea.facet.KotlinFacet import java.io.File +import java.io.IOException class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService() { override fun getTargetDataKey() = ProjectKeys.MODULE + private fun shouldCreateEmptySourceRoots( + moduleDataNode: DataNode, + module: Module + ): Boolean { + val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false + if (projectDataNode.getUserData(CREATE_EMPTY_DIRECTORIES) == true) return true + + val projectSystemId = projectDataNode.data.owner + val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId) + + val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false + return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false + } + override fun postProcess( toImport: MutableCollection>, projectData: ProjectData?, @@ -42,6 +62,7 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService, - rootModel: ModifiableRootModel + rootModel: ModifiableRootModel, + shouldCreateEmptySourceRoots: Boolean ) { val parent = findParentContentEntry(sourceRoot, rootModel.contentEntries.stream()) ?: return val url = FilePaths.pathToIdeaUrl(sourceRoot) parent.addSourceFolder(url, type) + if (shouldCreateEmptySourceRoots) { + ExternalSystemApiUtil.doWriteAction { + try { + VfsUtil.createDirectoryIfMissing(sourceRoot.path) + } catch (e: IOException) { + LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e) + } + } + } + } + + companion object { + private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java) } } \ No newline at end of file diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.173 b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.173 index 532293f91fc..6bc64536baa 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.173 +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.173 @@ -7,15 +7,21 @@ package org.jetbrains.kotlin.android.configure import com.android.tools.idea.gradle.project.model.AndroidModuleModel import com.android.tools.idea.gradle.util.FilePaths +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager import com.intellij.openapi.externalSystem.model.DataNode import com.intellij.openapi.externalSystem.model.ProjectKeys import com.intellij.openapi.externalSystem.model.project.ModuleData import com.intellij.openapi.externalSystem.model.project.ProjectData import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService +import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.util.containers.stream import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.jps.model.module.JpsModuleSourceRootType @@ -26,10 +32,25 @@ import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService import org.jetbrains.kotlin.idea.configuration.kotlinAndroidSourceSets import org.jetbrains.kotlin.idea.facet.KotlinFacet import java.io.File +import java.io.IOException class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService() { override fun getTargetDataKey() = ProjectKeys.MODULE + private fun shouldCreateEmptySourceRoots( + moduleDataNode: DataNode, + module: Module + ): Boolean { + val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false + if (projectDataNode.getUserData(CREATE_EMPTY_DIRECTORIES) == true) return true + + val projectSystemId = projectDataNode.data.owner + val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId) + + val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false + return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false + } + override fun postProcess( toImport: MutableCollection>, projectData: ProjectData?, @@ -40,6 +61,7 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService, - rootModel: ModifiableRootModel + rootModel: ModifiableRootModel, + shouldCreateEmptySourceRoots: Boolean ) { val parent = FilePaths.findParentContentEntry(sourceRoot, rootModel.contentEntries) ?: return val url = FilePaths.pathToIdeaUrl(sourceRoot) parent.addSourceFolder(url, type) + if (shouldCreateEmptySourceRoots) { + ExternalSystemApiUtil.doWriteAction { + try { + VfsUtil.createDirectoryIfMissing(sourceRoot.path) + } catch (e: IOException) { + LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e) + } + } + } + } + + companion object { + private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java) } } \ No newline at end of file diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.181 b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.181 index 539e7529cf5..5a9ae3abb36 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.181 +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.181 @@ -8,15 +8,20 @@ package org.jetbrains.kotlin.android.configure import com.android.tools.idea.gradle.project.model.AndroidModuleModel import com.android.tools.idea.gradle.util.ContentEntries.findParentContentEntry import com.android.tools.idea.gradle.util.FilePaths +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager import com.intellij.openapi.externalSystem.model.DataNode import com.intellij.openapi.externalSystem.model.ProjectKeys import com.intellij.openapi.externalSystem.model.project.ModuleData import com.intellij.openapi.externalSystem.model.project.ProjectData import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService +import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.vfs.VfsUtil import com.intellij.util.containers.stream import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType @@ -28,10 +33,25 @@ import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService import org.jetbrains.kotlin.idea.configuration.kotlinAndroidSourceSets import org.jetbrains.kotlin.idea.facet.KotlinFacet import java.io.File +import java.io.IOException class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService() { override fun getTargetDataKey() = ProjectKeys.MODULE + private fun shouldCreateEmptySourceRoots( + moduleDataNode: DataNode, + module: Module + ): Boolean { + val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false + if (projectDataNode.getUserData(CREATE_EMPTY_DIRECTORIES) == true) return true + + val projectSystemId = projectDataNode.data.owner + val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId) + + val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false + return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false + } + override fun postProcess( toImport: MutableCollection>, projectData: ProjectData?, @@ -42,6 +62,7 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService, - rootModel: ModifiableRootModel + rootModel: ModifiableRootModel, + shouldCreateEmptySourceRoots: Boolean ) { val parent = findParentContentEntry(sourceRoot, rootModel.contentEntries.stream()) ?: return val url = FilePaths.pathToIdeaUrl(sourceRoot) parent.addSourceFolder(url, type) + if (shouldCreateEmptySourceRoots) { + ExternalSystemApiUtil.doWriteAction { + try { + VfsUtil.createDirectoryIfMissing(sourceRoot.path) + } catch (e: IOException) { + LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e) + } + } + } + } + + companion object { + private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java) } } \ No newline at end of file diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as31 b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as31 index 409ba33a875..4a319a8f140 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as31 +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as31 @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.android.configure import com.android.tools.idea.gradle.project.model.AndroidModuleModel import com.android.tools.idea.gradle.util.ContentEntries.findParentContentEntry import com.android.tools.idea.io.FilePaths +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager import com.intellij.openapi.externalSystem.model.DataNode import com.intellij.openapi.externalSystem.model.ProjectKeys import com.intellij.openapi.externalSystem.model.project.ContentRootData @@ -16,9 +18,12 @@ import com.intellij.openapi.externalSystem.model.project.ProjectData import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService +import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.vfs.VfsUtil import com.intellij.util.containers.stream import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType @@ -32,10 +37,25 @@ import org.jetbrains.kotlin.idea.configuration.kotlinAndroidSourceSets import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData import org.jetbrains.kotlin.idea.facet.KotlinFacet import java.io.File +import java.io.IOException class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService() { override fun getTargetDataKey() = ProjectKeys.MODULE + private fun shouldCreateEmptySourceRoots( + moduleDataNode: DataNode, + module: Module + ): Boolean { + val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false + if (projectDataNode.getUserData(CREATE_EMPTY_DIRECTORIES) == true) return true + + val projectSystemId = projectDataNode.data.owner + val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId) + + val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false + return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false + } + override fun postProcess( toImport: MutableCollection>, projectData: ProjectData?, @@ -55,6 +75,7 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService, - rootModel: ModifiableRootModel + rootModel: ModifiableRootModel, + shouldCreateEmptySourceRoots: Boolean ) { val parent = findParentContentEntry(sourceRoot, rootModel.contentEntries.stream()) ?: return val url = FilePaths.pathToIdeaUrl(sourceRoot) parent.addSourceFolder(url, type) + if (shouldCreateEmptySourceRoots) { + ExternalSystemApiUtil.doWriteAction { + try { + VfsUtil.createDirectoryIfMissing(sourceRoot.path) + } catch (e: IOException) { + LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e) + } + } + } + } + + companion object { + private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java) } } \ No newline at end of file diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as32 b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as32 index 2a3f1a8edad..a5e88fda92f 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as32 +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleMPPModuleDataService.kt.as32 @@ -8,15 +8,20 @@ package org.jetbrains.kotlin.android.configure import com.android.tools.idea.gradle.project.model.AndroidModuleModel import com.android.tools.idea.gradle.util.ContentEntries.findParentContentEntry import com.android.tools.idea.io.FilePaths +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager import com.intellij.openapi.externalSystem.model.DataNode import com.intellij.openapi.externalSystem.model.ProjectKeys import com.intellij.openapi.externalSystem.model.project.ModuleData import com.intellij.openapi.externalSystem.model.project.ProjectData import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService +import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.vfs.VfsUtil import com.intellij.util.containers.stream import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType @@ -28,10 +33,25 @@ import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService import org.jetbrains.kotlin.idea.configuration.kotlinAndroidSourceSets import org.jetbrains.kotlin.idea.facet.KotlinFacet import java.io.File +import java.io.IOException class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService() { override fun getTargetDataKey() = ProjectKeys.MODULE + private fun shouldCreateEmptySourceRoots( + moduleDataNode: DataNode, + module: Module + ): Boolean { + val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false + if (projectDataNode.getUserData(CREATE_EMPTY_DIRECTORIES) == true) return true + + val projectSystemId = projectDataNode.data.owner + val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId) + + val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false + return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false + } + override fun postProcess( toImport: MutableCollection>, projectData: ProjectData?, @@ -42,6 +62,7 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService, - rootModel: ModifiableRootModel + rootModel: ModifiableRootModel, + shouldCreateEmptySourceRoots: Boolean ) { val parent = findParentContentEntry(sourceRoot, rootModel.contentEntries.stream()) ?: return val url = FilePaths.pathToIdeaUrl(sourceRoot) parent.addSourceFolder(url, type) + if (shouldCreateEmptySourceRoots) { + ExternalSystemApiUtil.doWriteAction { + try { + VfsUtil.createDirectoryIfMissing(sourceRoot.path) + } catch (e: IOException) { + LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e) + } + } + } + } + + companion object { + private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java) } } \ No newline at end of file