Skip to content

Introduce utbot-android-studio module and fix dependencies installation #1180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ideType=IC

# In order to run Android Studion instead of Intellij Community,
# specify the path to your Android Studio installation
//androidStudioPath=D:/AS2021
//androidStudioPath=your_path_to_android_studio

pythonCommunityPluginVersion=222.4167.37
#Version numbers: https://plugins.jetbrains.com/plugin/631-python/versions
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ include 'utbot-maven'
include 'utbot-summary-tests'
include 'utbot-framework-test'
include 'utbot-rd'
include 'utbot-android-studio'

46 changes: 46 additions & 0 deletions utbot-android-studio/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
plugins {
id("org.jetbrains.intellij") version "1.7.0"
}

intellij {
/*
The list of Android Studio releases can be found here https://plugins.jetbrains.com/docs/intellij/android-studio-releases-list.html
For each release a compatible Intellij Idea version can be found in the right column. Specify it in "version.set("...")

NOTE!!!
We use Android Studio Chipmunk (2021.2.1), although Android Studio Dolphin (2021.3.1) has been released.
The reason is that a version of Kotlin plugin compatible with Android Studio is required.
The list of Kotlin plugin releases can be found here https://plugins.jetbrains.com/plugin/6954-kotlin/versions/stable
The last compatible with AS plugin version on 19 Oct 2022 is Kotlin 212-1.7.10-release-333-AS5457.46,
it is not compatible with Dolphin release (https://plugins.jetbrains.com/plugin/6954-kotlin/versions/stable/193255).
*/

val androidPlugins = listOf("org.jetbrains.android")

val jvmPlugins = listOf(
"java",
"org.jetbrains.kotlin:212-1.7.10-release-333-AS5457.46"
)

plugins.set(jvmPlugins + androidPlugins)

version.set("212.5712.43")
type.set("IC")
}

project.tasks.asMap["runIde"]?.enabled = false

tasks {
compileKotlin {
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs + listOf("-Xallow-result-return-type", "-Xsam-conversions=class")
allWarningsAsErrors = false
}
}

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package org.androidstudio.plugin.util

import com.android.tools.idea.gradle.AndroidGradleJavaProjectModelModifier
import com.android.tools.idea.gradle.dsl.api.GradleBuildModel
import com.android.tools.idea.gradle.dsl.api.dependencies.ArtifactDependencySpec
import com.android.tools.idea.gradle.dsl.api.dependencies.CommonConfigurationNames
import com.android.tools.idea.gradle.project.sync.GradleSyncInvoker
import com.android.tools.idea.gradle.project.sync.GradleSyncListener
import com.android.tools.idea.gradle.project.sync.idea.GradleSyncExecutor
import com.android.tools.idea.gradle.util.GradleUtil
import com.android.tools.idea.project.AndroidProjectInfo
import com.android.tools.idea.projectsystem.TestArtifactSearchScopes
import com.google.wireless.android.sdk.stats.GradleSyncStats
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.command.undo.BasicUndoableAction
import com.intellij.openapi.command.undo.UndoManager
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.DependencyScope
import com.intellij.openapi.roots.ExternalLibraryDescriptor
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.concurrency.AsyncPromise
import org.jetbrains.concurrency.Promise

class UtAndroidGradleJavaProjectModelModifier : AndroidGradleJavaProjectModelModifier() {
override fun addExternalLibraryDependency(
modules: Collection<Module?>,
descriptor: ExternalLibraryDescriptor,
scope: DependencyScope
): Promise<Void?>? {
val module = ContainerUtil.getFirstItem(modules) ?: return null

if (!isAndroidGradleProject(module.project)) {
return null
}

val dependencySpec = ArtifactDependencySpec.create(descriptor.libraryArtifactId, descriptor.libraryGroupId, descriptor.preferredVersion)
return addExternalLibraryDependency(module, dependencySpec, scope)

}

private fun addExternalLibraryDependency(
module: Module,
dependencySpec: ArtifactDependencySpec,
scope: DependencyScope,
): Promise<Void?>? {
val project = module.project
val openedFile = FileEditorManagerEx.getInstanceEx(project).currentFile
val buildModelsToUpdate: MutableList<GradleBuildModel> = ArrayList()

val buildModel = GradleBuildModel.get(module) ?: return null
val configurationName = getConfigurationName(module, scope, openedFile)
val dependencies = buildModel.dependencies()
dependencies.addArtifact(configurationName, dependencySpec)
buildModelsToUpdate.add(buildModel)

WriteCommandAction.writeCommandAction(project).withName("Add Gradle Library Dependency").run<RuntimeException> {
buildModelsToUpdate.forEach { buildModel -> buildModel.applyChanges() }
registerUndoAction(project)
}

return doAndroidGradleSync(project, GradleSyncStats.Trigger.TRIGGER_MODIFIER_ADD_LIBRARY_DEPENDENCY)
}

private fun getConfigurationName(module: Module, scope: DependencyScope, openedFile: VirtualFile?): String =
GradleUtil.mapConfigurationName(
getLegacyConfigurationName(module, scope, openedFile),
GradleUtil.getAndroidGradleModelVersionInUse(module),
false
)

private fun getLegacyConfigurationName(
module: Module,
scope: DependencyScope,
openedFile: VirtualFile?
): String {
if (!scope.isForProductionCompile) {
val testScopes = TestArtifactSearchScopes.getInstance(module)
if (testScopes != null && openedFile != null) {
return if (testScopes.isAndroidTestSource(openedFile)) CommonConfigurationNames.ANDROID_TEST_COMPILE else CommonConfigurationNames.TEST_COMPILE
}
}
return CommonConfigurationNames.COMPILE
}

private fun registerUndoAction(project: Project) {
UndoManager.getInstance(project).undoableActionPerformed(object : BasicUndoableAction() {

override fun undo() {
doAndroidGradleSync(project, GradleSyncStats.Trigger.TRIGGER_MODIFIER_ACTION_UNDONE)

}

override fun redo() {
doAndroidGradleSync(project, GradleSyncStats.Trigger.TRIGGER_MODIFIER_ACTION_REDONE)
}
})
}

private fun isAndroidGradleProject(project: Project): Boolean = AndroidProjectInfo.getInstance(project).requiresAndroidModel()

private fun doAndroidGradleSync(project: Project, trigger: GradleSyncStats.Trigger): AsyncPromise<Void?> {
val promise = AsyncPromise<Void?>()
val request = GradleSyncInvoker.Request(trigger)
val listener = object : GradleSyncListener {
override fun syncSucceeded(project: Project) {
promise.setResult(null)
}

override fun syncFailed(project: Project, errorMessage: String) {
promise.setError(errorMessage)
}
}
GradleSyncExecutor(project).sync(request, listener)

return promise
}
}
2 changes: 2 additions & 0 deletions utbot-intellij/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,6 @@ dependencies {
//api(project(":utbot-analytics"))
testImplementation("org.mock-server:mockserver-netty:5.4.1")
testApi(project(":utbot-framework"))

implementation(project(":utbot-android-studio"))
}
1 change: 1 addition & 0 deletions utbot-intellij/src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<registryKey defaultValue="false" description="Enable editing Kotlin test files" key="kotlin.ultra.light.classes.empty.text.range"/>
<postStartupActivity implementation="org.utbot.intellij.plugin.ui.GotItTooltipActivity"/>
<projectModelModifier implementation="org.utbot.intellij.plugin.util.UtProjectModelModifier"/>
<projectModelModifier implementation="org.androidstudio.plugin.util.UtAndroidGradleJavaProjectModelModifier" order="first"/>
<!--Documentation-->
<customJavadocTagProvider implementation="org.utbot.intellij.plugin.javadoc.UtCustomJavaDocTagProvider"/>
<lang.documentationProvider language="JAVA" order="first" implementationClass="org.utbot.intellij.plugin.javadoc.UtDocumentationProvider"/>
Expand Down