Explorar o código

Merge pull request #54 from windchargerj/bugFix

BugFix for IDEA Community and Configuration issues
ruki hai 1 ano
pai
achega
2450ea86d1

+ 52 - 17
build.gradle.kts

@@ -1,3 +1,4 @@
+import org.jetbrains.intellij.IntelliJPluginExtension
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 fun properties(key: String) = project.findProperty(key).toString()
@@ -6,16 +7,38 @@ fun properties(key: String) = project.findProperty(key).toString()
 val localChangeNotes: String = file("${projectDir}/change-notes.html").readText(Charsets.UTF_8)
 val localDescription: String = file("${projectDir}/description.html").readText(Charsets.UTF_8)
 
-//testing ide (true : clion , false : intellij)
-//val testIde:String = if(properties("testInClion").toBoolean()) "CL" else "IC"
-val testIde: String = when (2) {
-    0 -> "IC"
-    1 -> "IU"
-    2 -> "CL"
+val type = mapOf(
+    "IC" to "ideaIC",
+    "IU" to "ideaIU",
+    "CL" to "clion",
+    "PY" to "pycharmPY"
+)
+/*
+* Best practice:
+* Use CL for both building and running.
+* If you lack a license, use CLI for building and IC for running.
+* Specify the ideDir path as needed.
+* */
+
+val buildIdeType: String = when (2) {
+    0 -> "IC" // SSH-related functions cannot be built by the Community version.
+    1 -> "IU" // To build with Ultimate version does not require a license.
+    2 -> "CL" // C/C++ intellij-sense is included.
     3 -> "PY"
     else -> "IC"
 }
 
+val buildIdeVersion = "2024.2"
+
+val runIdeType: String = when (2) {
+    0 -> "IC" // You can build with the Ultimate version, but run with the Community version.
+    1 -> "IU" // It may require a license to run with the Ultimate version.
+    2 -> "CL"  // It includes C/C++ related functions, along with functions in the Ultimate version.
+    3 -> "PY"
+    else -> "IC"
+}
+
+val runIdeVersion = "2024.2"
 
 plugins {
     id("java")
@@ -37,8 +60,8 @@ repositories {
 }
 
 intellij {
-    type.set(testIde)
-    version.set("2024.2")
+    type.set(buildIdeType)
+    version.set(buildIdeVersion)
     downloadSources.set(true)
     ideaDependencyCachePath.set(dependencyCachePath)
     updateSinceUntilBuild.set(true)
@@ -88,14 +111,28 @@ tasks {
             )
         )
     }
-    runIde {
-        when (2) {
-            0 -> ideDir.set(file("deps/ideaIC-2024.2"))
-            1 -> ideDir.set(file("deps/ideaIU-2024.2"))
-            2 -> ideDir.set(file("deps/clion-2024.2"))
-            3 -> ideDir.set(file("deps/pycharmPY-2024.2"))
-            else -> ideDir.set(file("deps/ideaIC-2024.2"))
+
+    // Execute this downloadIde gradle task if missing build.txt in runIde task.
+    register("downloadIde") {
+        group = "Custom Tasks"
+        description = "Downloads a specific version and type of IntelliJ IDEA based on provided parameters."
+
+        doFirst {
+            println("Executing downloadIde task")
+            // 动态设置 IntelliJ 插件配置
+            val intellijExtension = project.extensions.getByType(IntelliJPluginExtension::class.java)
+            val ideVersion = project.findProperty("ideVersion")?.toString() ?: runIdeVersion
+            val ideType = project.findProperty("ideType")?.toString() ?: runIdeType
+
+            intellijExtension.version.set(ideVersion)
+            intellijExtension.type.set(ideType)
         }
+
+        finalizedBy("setupDependencies")
+    }
+
+    runIde {
+        ideDir.set(file("deps/${type[runIdeType]}-$runIdeVersion"))
     }
 }
 
@@ -104,8 +141,6 @@ dependencies {
     testImplementation("io.mockk:mockk:1.13.12")
 }
 
-
-
 val Project.dependencyCachePath
     get(): String {
         val cachePath = file("${rootProject.projectDir}/deps")

+ 8 - 4
src/main/kotlin/io/xmake/project/XMakeProjectToolkitConfigurable.kt

@@ -1,7 +1,6 @@
 package io.xmake.project
 
 import com.intellij.openapi.options.Configurable
-import com.intellij.openapi.project.Project
 import com.intellij.openapi.ui.Messages
 import com.intellij.ui.ColoredListCellRenderer
 import com.intellij.ui.SimpleTextAttributes
@@ -15,9 +14,9 @@ import javax.swing.DefaultListModel
 import javax.swing.JComponent
 import javax.swing.JList
 
-class XMakeProjectToolkitConfigurable(val project: Project) : Configurable, Configurable.NoScroll {
+class XMakeProjectToolkitConfigurable : Configurable, Configurable.NoScroll {
     override fun createComponent(): JComponent {
-        val registeredToolkit = ToolkitManager.getInstance().state.registeredToolkits
+        val registeredToolkit = ToolkitManager.getInstance().getRegisteredToolkits()
         val listModel = DefaultListModel<ToolkitListItem>().apply { registeredToolkit.forEach {
             addElement(ToolkitListItem.ToolkitItem(it).asRegistered()) }
         }
@@ -50,7 +49,12 @@ class XMakeProjectToolkitConfigurable(val project: Project) : Configurable, Conf
 
         decorator.setRemoveAction {
             val toolkit = (toolkitList.selectedValue as ToolkitListItem.ToolkitItem).toolkit
-            if (Messages.showYesNoDialog(project, "Unregister ${toolkit.name}?", "Unregister Toolkit", Messages.getQuestionIcon()) == Messages.YES) {
+            if (Messages.showYesNoDialog(
+                    "Unregister ${toolkit.name}?",
+                    "Unregister Toolkit",
+                    Messages.getQuestionIcon()
+                ) == Messages.YES
+            ) {
                 ToolkitManager.getInstance().unregisterToolkit(toolkit)
                 listModel.removeElement(toolkitList.selectedValue)
             }

+ 41 - 37
src/main/kotlin/io/xmake/project/directory/ui/DirectoryBrowser.kt

@@ -13,6 +13,7 @@ import com.intellij.ssh.interaction.PlatformSshPasswordProvider
 import com.intellij.ssh.ui.sftpBrowser.RemoteBrowserDialog
 import com.intellij.ssh.ui.sftpBrowser.SftpRemoteBrowserProvider
 import io.xmake.project.toolkit.Toolkit
+import io.xmake.project.toolkit.ToolkitHost
 import io.xmake.project.toolkit.ToolkitHostType.*
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.runBlocking
@@ -48,45 +49,31 @@ class DirectoryBrowser(val project: Project?) : TextFieldWithBrowseButton() {
         return wslBrowseFolderListener
     }
 
-    private fun createSftpBrowseListener(target: SshConfig): ActionListener {
-        val sftpChannel = runBlocking(Dispatchers.Default){
-            ConnectionBuilder(target.host)
-                .withSshPasswordProvider(PlatformSshPasswordProvider(target.copyToCredentials()))
-                .openFailSafeSftpChannel()
-        }
-        val sftpRemoteBrowserProvider = SftpRemoteBrowserProvider(sftpChannel)
-        val remoteBrowseFolderListener = ActionListener {
-            text = RemoteBrowserDialog(
-                sftpRemoteBrowserProvider,
-                project,
-                true,
-                withCreateDirectoryButton = true
-            ).apply { showAndGet() }.getResult()
-        }
-        return remoteBrowseFolderListener
+    fun addBrowserListenerByToolkit(toolkit: Toolkit){
+        addBrowserListenerByHostType(toolkit.host)
     }
 
-    fun addBrowserListenerByToolkit(toolkit: Toolkit){
-        with(toolkit){
-            when (host.type) {
-                LOCAL -> {
-                    val localBrowseListener = createLocalBrowseListener()
-                    addActionListener(localBrowseListener)
-                    listeners.add(localBrowseListener)
-                    Log.debug("addActionListener local: $localBrowseListener")
-                }
-                WSL -> {
-                    val wslBrowseListener = createWslBrowseListener(host.target as WSLDistribution)
-                    addActionListener(wslBrowseListener)
-                    listeners.add(wslBrowseListener)
-                    Log.debug("addActionListener wsl: $wslBrowseListener")
-                }
-                SSH -> {
-                    val sftpBrowseListener = createSftpBrowseListener(host.target as SshConfig)
-                    addActionListener(sftpBrowseListener)
-                    listeners.add(sftpBrowseListener)
-                    Log.debug("addActionListener remote: $sftpBrowseListener")
-                }
+    fun addBrowserListenerByHostType(host: ToolkitHost) {
+        when (host.type) {
+            LOCAL -> {
+                val localBrowseListener = createLocalBrowseListener()
+                addActionListener(localBrowseListener)
+                listeners.add(localBrowseListener)
+                Log.debug("addActionListener local: $localBrowseListener")
+            }
+
+            WSL -> {
+                val wslBrowseListener = createWslBrowseListener(host.target as WSLDistribution)
+                addActionListener(wslBrowseListener)
+                listeners.add(wslBrowseListener)
+                Log.debug("addActionListener wsl: $wslBrowseListener")
+            }
+
+            SSH -> {
+                val sftpBrowseListener = createSftpBrowseListener(host.target as SshConfig)
+                addActionListener(sftpBrowseListener)
+                listeners.add(sftpBrowseListener)
+                Log.debug("addActionListener remote: $sftpBrowseListener")
             }
         }
     }
@@ -101,4 +88,21 @@ class DirectoryBrowser(val project: Project?) : TextFieldWithBrowseButton() {
     }
 }
 
+fun DirectoryBrowser.createSftpBrowseListener(target: SshConfig): ActionListener {
+    val sftpChannel = runBlocking(Dispatchers.Default) {
+        ConnectionBuilder(target.host)
+            .withSshPasswordProvider(PlatformSshPasswordProvider(target.copyToCredentials()))
+            .openFailSafeSftpChannel()
+    }
+    val sftpRemoteBrowserProvider = SftpRemoteBrowserProvider(sftpChannel)
+    val remoteBrowseFolderListener = ActionListener {
+        text = RemoteBrowserDialog(
+            sftpRemoteBrowserProvider,
+            project,
+            true,
+            withCreateDirectoryButton = true
+        ).apply { showAndGet() }.getResult()
+    }
+    return remoteBrowseFolderListener
+}
 

+ 1 - 1
src/main/kotlin/io/xmake/project/target/TargetManager.kt

@@ -18,7 +18,7 @@ class TargetManager(
     private val scope: CoroutineScope,
 ) {
 
-    fun detectXmakeTarget(toolkit: Toolkit, workingDirectory: String): List<String> = runBlocking(Dispatchers.IO) {
+    fun detectXMakeTarget(toolkit: Toolkit, workingDirectory: String): List<String> = runBlocking(Dispatchers.IO) {
         val process = probeXmakeTargetCommand
             .withExePath(toolkit.path)
             .withWorkDirectory(workingDirectory)

+ 12 - 6
src/main/kotlin/io/xmake/project/toolkit/ToolkitManager.kt

@@ -25,7 +25,7 @@ import java.util.*
 @State(name = "toolkits", storages = [Storage("xmakeToolkits.xml")])
 class ToolkitManager(private val scope: CoroutineScope) : PersistentStateComponent<ToolkitManager.State> {
 
-    val toolkitSet = mutableSetOf<Toolkit>()
+    val fetchedToolkitsSet = mutableSetOf<Toolkit>()
     private lateinit var detectionJob: Job
     private lateinit var validateJob: Job
     private var storage: State = State()
@@ -103,7 +103,7 @@ class ToolkitManager(private val scope: CoroutineScope) : PersistentStateCompone
     }
 
     @OptIn(ExperimentalCoroutinesApi::class)
-    fun detectXmakeToolkits(project: Project?) {
+    fun detectXMakeToolkits(project: Project?) {
         detectionJob = scope.launch {
             val toolkitFlow = toolkitHostFlow(project)
 
@@ -145,7 +145,7 @@ class ToolkitManager(private val scope: CoroutineScope) : PersistentStateCompone
 
             versionFlow.collect { toolkit ->
                 // Todo: Consider cache
-                toolkitSet.add(toolkit)
+                fetchedToolkitsSet.add(toolkit)
                 listenerList.forEach { listener ->
                     listener.onToolkitDetected(ToolkitDetectEvent(toolkit))
                 }
@@ -162,7 +162,7 @@ class ToolkitManager(private val scope: CoroutineScope) : PersistentStateCompone
     }
 
     // Todo: Validate toolkit.
-    fun validateXmakeToolkit(){
+    fun validateXMakeToolkit() {
         scope.launch {
             try {
                 validateJob = launch { validateToolkits() }
@@ -191,9 +191,9 @@ class ToolkitManager(private val scope: CoroutineScope) : PersistentStateCompone
     }
 
     override fun loadState(state: State) {
-        state.registeredToolkits.forEach{
+        state.registeredToolkits.forEach {
             registerToolkit(it)
-            toolkitSet.add(it)
+            fetchedToolkitsSet.add(it)
         }
         this.storage = state
     }
@@ -209,6 +209,8 @@ class ToolkitManager(private val scope: CoroutineScope) : PersistentStateCompone
         toolkit.isRegistered = true
         if (state.registeredToolkits.add(toolkit)){
             loadToolkit(toolkit)
+        } else {
+            loadToolkit(findRegisteredToolkitById(toolkit.id)!!)
         }
         Log.info("load registered toolkit: ${toolkit.name}, ${toolkit.id}")
     }
@@ -231,6 +233,10 @@ class ToolkitManager(private val scope: CoroutineScope) : PersistentStateCompone
         return state.registeredToolkits.find { it.id == id }
     }
 
+    fun getRegisteredToolkits(): List<Toolkit> {
+        return state.registeredToolkits.filterNot { (it.host.type == SSH && PlatformUtils.isCommunityEdition()) }
+    }
+
     companion object {
         fun  getInstance(): ToolkitManager = service()
         private val Log = logger<ToolkitManager>()

+ 6 - 16
src/main/kotlin/io/xmake/project/toolkit/ui/ToolkitComboBox.kt

@@ -84,7 +84,7 @@ class ToolkitComboBox(toolkitProperty: KMutableProperty0<Toolkit?>) : ComboBox<T
                 with(model) {
                     clear()
                     add(ToolkitListItem.NoneItem())
-                    service.state.registeredToolkits.forEach {
+                    service.getRegisteredToolkits().forEach {
                         add(ToolkitListItem.ToolkitItem(it).asRegistered())
                     }
                 }
@@ -94,7 +94,7 @@ class ToolkitComboBox(toolkitProperty: KMutableProperty0<Toolkit?>) : ComboBox<T
                 }
 
                 // to select configuration-level activated toolkit
-                item = if (service.state.registeredToolkits.isEmpty() || itemToolkit == null) {
+                item = if (service.getRegisteredToolkits().isEmpty() || itemToolkit == null) {
                     model.items.first()
                 } else {
                     model.items.find { it.id == itemToolkit.id }.let {
@@ -107,7 +107,7 @@ class ToolkitComboBox(toolkitProperty: KMutableProperty0<Toolkit?>) : ComboBox<T
                 }
 
                 val project = ProjectManager.getInstanceIfCreated()?.defaultProject
-                service.detectXmakeToolkits(project)
+                service.detectXMakeToolkits(project)
             }
 
             override fun popupMenuWillBecomeInvisible(e: PopupMenuEvent?) {
@@ -135,23 +135,13 @@ class ToolkitComboBox(toolkitProperty: KMutableProperty0<Toolkit?>) : ComboBox<T
                 val toolkitListItem = it.item as ToolkitListItem
                 if (toolkitListItem is ToolkitListItem.ToolkitItem) {
                     with(service) {
-                        val fetchedToolkit = toolkitSet.find { it.id == toolkitListItem.id }
+                        val fetchedToolkit = fetchedToolkitsSet.find { it.id == toolkitListItem.id }
 
                         if (fetchedToolkit != null) {
                             // check whether registered or not
-                            state.registeredToolkits.run {
+                            getRegisteredToolkits().run {
                                 if (findRegisteredToolkitById(fetchedToolkit.id) == null) {
-                                    add(fetchedToolkit)
-                                }
-                            }
-                        } else {
-                            // selectedItem toolkit is not in toolkitSet
-                        }
-                        if (fetchedToolkit != null) {
-                            // check whether registered or not
-                            state.registeredToolkits.run {
-                                if (findRegisteredToolkitById(fetchedToolkit.id) == null) {
-                                    add(fetchedToolkit)
+                                    registerToolkit(fetchedToolkit)
                                 }
                             }
                         } else {

+ 23 - 1
src/main/kotlin/io/xmake/run/XMakeRunConfiguration.kt

@@ -36,7 +36,7 @@ class XMakeRunConfiguration(
     var runPlatform: String = SystemUtils.platform()
 
     @OptionTag(tag = "architecture")
-    var runArchitecture: String = ""
+    var runArchitecture: String = getArchitecturesByPlatform(runPlatform).first()
 
     @OptionTag(tag = "mode")
     var runMode: String = "release"
@@ -145,6 +145,28 @@ class XMakeRunConfiguration(
     }
 
     companion object {
+
+        // the platforms
+        val platforms = arrayOf("macosx", "linux", "windows", "android", "iphoneos", "watchos", "mingw")
+
+        // the modes
+        val modes = arrayOf("release", "debug")
+
+        /*        // the architectures
+                val architectures: Array<String>
+                    get() = getArchitecturesByPlatform(runPlatform)*/
+
+        // get architectures by platform
+        fun getArchitecturesByPlatform(platform: String) = when (platform) {
+            "macosx", "linux", "mingw" -> arrayOf("x86_64", "i386", "arm64")
+            "windows" -> arrayOf("x86", "x64")
+            "iphoneos" -> arrayOf("arm64", "armv7", "armv7s", "x86_64", "i386")
+            "watchos" -> arrayOf("armv7s", "i386")
+            "android" -> arrayOf("armv7-a", "armv5te", "armv6", "armv8-a", "arm64-v8a")
+            else -> arrayOf()
+        }
+
+
         private val Log = Logger.getInstance(XMakeRunConfiguration::class.java.getName())
     }
 }

+ 13 - 6
src/main/kotlin/io/xmake/run/XMakeRunConfigurationEditor.kt

@@ -21,6 +21,9 @@ import io.xmake.project.toolkit.Toolkit
 import io.xmake.project.toolkit.ToolkitHostType.*
 import io.xmake.project.toolkit.ui.ToolkitComboBox
 import io.xmake.project.toolkit.ui.ToolkitListItem
+import io.xmake.run.XMakeRunConfiguration.Companion.getArchitecturesByPlatform
+import io.xmake.run.XMakeRunConfiguration.Companion.modes
+import io.xmake.run.XMakeRunConfiguration.Companion.platforms
 import io.xmake.shared.xmakeConfiguration
 import io.xmake.utils.execute.SyncDirection
 import io.xmake.utils.execute.syncProjectBySftp
@@ -48,13 +51,13 @@ class XMakeRunConfigurationEditor(
     private val targetsModel = DefaultComboBoxModel<String>()
     private val targetsComboBox = ComboBox(targetsModel).apply { item = runConfiguration.runTarget }
 
-    private val platformsModel = DefaultComboBoxModel(project.xmakeConfiguration.platforms)
+    private val platformsModel = DefaultComboBoxModel(platforms)
     private val platformsComboBox = ComboBox(platformsModel).apply { item = runConfiguration.runPlatform }
 
-    private val architecturesModel = DefaultComboBoxModel(project.xmakeConfiguration.architectures)
+    private val architecturesModel = DefaultComboBoxModel(getArchitecturesByPlatform(runConfiguration.runPlatform))
     private val architecturesComboBox = ComboBox(architecturesModel).apply { item = runConfiguration.runArchitecture }
 
-    private val modesModel = DefaultComboBoxModel(project.xmakeConfiguration.modes)
+    private val modesModel = DefaultComboBoxModel(modes)
     private val modesComboBox = ComboBox(modesModel).apply { item = runConfiguration.runMode }
 
     private val runArguments = RawCommandLineEditor()
@@ -169,8 +172,12 @@ class XMakeRunConfigurationEditor(
                 row {
                     cell(platformsComboBox).applyToComponent {
                         addItemListener {
-                            architecturesModel.removeAllElements()
-                            architecturesModel.addAll(project.xmakeConfiguration.architectures.toMutableList())
+                            val architectures = getArchitecturesByPlatform(selectedItem as String)
+                            with(architecturesModel) {
+                                removeAllElements()
+                                addAll(architectures.toMutableList())
+                                selectedItem = architectures.first()
+                            }
                         }
                     }.align(AlignX.FILL)
                 }
@@ -204,7 +211,7 @@ class XMakeRunConfigurationEditor(
                         with(runConfiguration) {
                             if (runToolkit != null && runWorkingDir.isNotEmpty()) {
                                 TargetManager.getInstance(project)
-                                    .detectXmakeTarget(runToolkit!!, runConfiguration.runWorkingDir).forEach { target ->
+                                    .detectXMakeTarget(runToolkit!!, runConfiguration.runWorkingDir).forEach { target ->
                                         targetsModel.addElement(target)
                                     }
                             }

+ 6 - 27
src/main/kotlin/io/xmake/shared/XMakeConfiguration.kt

@@ -13,16 +13,6 @@ import io.xmake.utils.exception.XMakeRunConfigurationNotSetException
 @Service(Service.Level.PROJECT)
 class XMakeConfiguration(val project: Project) {
 
-    // the platforms
-    val platforms = arrayOf("macosx", "linux", "windows", "android", "iphoneos", "watchos", "mingw")
-
-    // the architectures
-    val architectures: Array<String>
-        get() = getArchitecturesByPlatform(configuration.runPlatform)
-
-    // the modes
-    val modes = arrayOf("release", "debug")
-
     val configuration: XMakeRunConfiguration
         get() {
             return RunManager.getInstance(project).selectedConfiguration?.configuration as? XMakeRunConfiguration
@@ -165,25 +155,14 @@ class XMakeConfiguration(val project: Project) {
             .withRedirectErrorStream(true)
     }
 
-    // ensure state
-    private fun ensureState() {
-        if (configuration.runArchitecture == "" && architectures.isNotEmpty()) {
-            configuration.runArchitecture = architectures[0]
-        }
-    }
+    /*    // ensure state
+        private fun ensureState() {
+            if (configuration.runArchitecture == "" && architectures.isNotEmpty()) {
+                configuration.runArchitecture = architectures[0]
+            }
+        }*/
 
     companion object {
-
-        // get architectures by platform
-        fun getArchitecturesByPlatform(platform: String) = when (platform) {
-            "macosx", "linux", "mingw" -> arrayOf("x86_64", "i386", "arm64")
-            "windows" -> arrayOf("x86", "x64")
-            "iphoneos" -> arrayOf("arm64", "armv7", "armv7s", "x86_64", "i386")
-            "watchos" -> arrayOf("armv7s", "i386")
-            "android" -> arrayOf("armv7-a", "armv5te", "armv6", "armv8-a", "arm64-v8a")
-            else -> arrayOf()
-        }
-
         // get log
         private val Log = Logger.getInstance(XMakeConfiguration::class.java.getName())
     }