Skip to content

Commit

Permalink
Added basic functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
JBou committed Jan 14, 2024
1 parent f450bdb commit c552479
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 113 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# idea-undelegate-run Changelog

## [Unreleased]
## [0.0.1]
### Added
- Ported functionality from the [original repository](https://github.com/Abnaxos/idea-undelegate-run)
- Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)
52 changes: 46 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# idea-undelegate-run
# Un-Delegate Run Actions IDEA Plugin

![Build](https://github.com/JBou/idea-undelegate-run/workflows/Build/badge.svg)
[![Version](https://img.shields.io/jetbrains/plugin/v/PLUGIN_ID.svg)](https://plugins.jetbrains.com/plugin/PLUGIN_ID)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/PLUGIN_ID.svg)](https://plugins.jetbrains.com/plugin/PLUGIN_ID)

## Template ToDo list
- [x] Create a new [IntelliJ Platform Plugin Template][template] project.
- [ ] Get familiar with the [template documentation][template].
- [ ] Adjust the [pluginGroup](./gradle.properties), [plugin ID](./src/main/resources/META-INF/plugin.xml) and [sources package](./src/main/kotlin).
- [ ] Adjust the plugin description in `README` (see [Tips][docs:plugin-description])
- [ ] Review the [Legal Agreements](https://plugins.jetbrains.com/docs/marketplace/legal-agreements.html?from=IJPluginTemplate).
Expand All @@ -16,14 +14,50 @@
- [ ] Set the [Deployment Token](https://plugins.jetbrains.com/docs/marketplace/plugin-upload.html?from=IJPluginTemplate).
- [ ] Click the <kbd>Watch</kbd> button on the top of the [IntelliJ Platform Plugin Template][template] to be notified about releases containing new features and fixes.

Description
------------

<!-- Plugin description -->
This Fancy IntelliJ Platform Plugin is going to be your implementation of the brilliant ideas that you have.
This is a small plugin for IDEA that allows to only delegate build actions to Gradle, but not run actions.
It's a proof of concept, I'm hoping to get this functionality integrated into IDEA.

This Plugin is based on https://github.com/Abnaxos/idea-undelegate-run.
All credits go to that project.
It was just updated to support newer IntelliJ versions.

This specific section is a source for the [plugin.xml](/src/main/resources/META-INF/plugin.xml) file which will be extracted by the [Gradle](/build.gradle.kts) during the build process.
Allows to delegate build actions to Gradle, but keep run actions in
IDEA.
This way, you get the best of both worlds: Gradle builds, IDEA
runs.
Enable and configure the un-delegation in `Settings / Build,
Execution, Deployment / Un-Delegate Run Actions`.
Tested with Gradle only, but it may also work with Maven
delegation.

To keep everything working, do not remove `<!-- ... -->` sections.
There is already an issue to add this functionality:
https://youtrack.jetbrains.com/issue/IDEA-176987/Delegate-only-build-to-Gradle
<!-- Plugin description end -->


Known Issues
------------

- Class reloading doesn't work. Class reloading actually never works when
delegating build/run actions to Gradle, so this isn't a new issue. But
the plugin unfortunately doesn't fix it.

Build
-----

```
./gradlew build
```

Usage
-----

The plugin adds a settings panel in *Build, Exection, Deployment / Build Tools / Un-Delegate Run Actions*.

## Installation

- Using the IDE built-in plugin system:
Expand All @@ -42,3 +76,9 @@ Plugin based on the [IntelliJ Platform Plugin Template][template].

[template]: https://github.com/JetBrains/intellij-platform-plugin-template
[docs:plugin-description]: https://plugins.jetbrains.com/docs/intellij/plugin-user-experience.html#plugin-description-and-presentation


License
-------

[WTFPL](http://www.wtfpl.net/)
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ platformVersion = 2022.3.3

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins =
platformPlugins = com.intellij.java, com.intellij.gradle

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 8.5
Expand Down
20 changes: 0 additions & 20 deletions src/main/kotlin/com/github/jbou/ideaundelegaterun/MyBundle.kt

This file was deleted.

117 changes: 117 additions & 0 deletions src/main/kotlin/com/github/jbou/ideaundelegaterun/ProjectPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.github.jbou.ideaundelegaterun

import com.intellij.execution.configurations.RunProfile
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.module.Module
import java.util.regex.Pattern
import java.util.regex.PatternSyntaxException

@State(name = "undelegate-run", reloadable = true, storages = [Storage("undelegate-run.xml")])
class ProjectPlugin : PersistentStateComponent<ProjectPlugin.State> {
private val stateLock = Any()
private var state: State? = null

init {
synchronized(stateLock) {
state = State()
}
}

override fun getState(): State {
synchronized(stateLock) {
return State(state)
}
}

override fun loadState(state: State) {
synchronized(stateLock) {
this.state = State(state)
}
}

class State {
var isEnabled: Boolean = true
private var excludedModules = ""
private var excludedRunConfigurations = ""

constructor()

constructor(that: State?) {
this.isEnabled = that!!.isEnabled
this.excludedModules = that.excludedModules
this.excludedRunConfigurations = that.excludedRunConfigurations
}

fun getExcludedModules(): String {
return excludedModules
}

fun setExcludedModules(excludedModules: String?) {
this.excludedModules = excludedModules ?: ""
}

fun getExcludedRunConfigurations(): String {
return excludedRunConfigurations
}

fun setExcludedRunConfigurations(excludedRunConfigurations: String?) {
this.excludedRunConfigurations = excludedRunConfigurations ?: ""
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val that = other as State
if (isEnabled != that.isEnabled) return false
if (excludedModules != that.excludedModules) return false
return excludedRunConfigurations == that.excludedRunConfigurations
}

override fun hashCode(): Int {
var result = (if (isEnabled) 1 else 0)
result = 31 * result + excludedModules.hashCode()
result = 31 * result + excludedRunConfigurations.hashCode()
return result
}
}

companion object {
private val LOG = Logger.getInstance(
ProjectPlugin::class.java
)

fun isEnabledFor(runProfile: RunProfile, module: Module?): Boolean {
if (module == null) {
return false
}
val state = module.project.getComponent(
ProjectPlugin::class.java
).getState()
if (!state.isEnabled) {
return false
}
if (isExcluded(state.getExcludedModules(), module.name)) {
return false
}
if (isExcluded(state.getExcludedRunConfigurations(), runProfile.name)) {
return false
}
return true
}

private fun isExcluded(pattern: String, string: String): Boolean {
if (pattern.isBlank()) {
return false
}
try {
return Pattern.compile(pattern).matcher(string).find()
} catch (e: PatternSyntaxException) {
LOG.error("Illegal pattern: $pattern", e)
return false
}
}
}
}
86 changes: 86 additions & 0 deletions src/main/kotlin/com/github/jbou/ideaundelegaterun/Settings.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.github.jbou.ideaundelegaterun

import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.VerticalFlowLayout
import com.intellij.ui.DocumentAdapter
import org.jetbrains.annotations.Nls
import java.awt.BorderLayout
import java.awt.Cursor
import javax.swing.*
import javax.swing.event.DocumentEvent

class Settings(project: Project) : Configurable {
private val plugin: ProjectPlugin? = project.getComponent(ProjectPlugin::class.java)

private var state: ProjectPlugin.State? = null

override fun getDisplayName(): @Nls(capitalization = Nls.Capitalization.Title) String {
return "Un-Delegate Run Actions"
}

override fun createComponent(): JComponent {
// nullability for searchable index builder
state = plugin().state
val container = JPanel(BorderLayout())
container.border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
val settings = JPanel(VerticalFlowLayout(true, false))
container.add(settings, BorderLayout.NORTH)
// enabled check box
var line = JPanel(BorderLayout())
val enabled = JCheckBox("Un-Delegate Run Actions")
enabled.isSelected = state!!.isEnabled
enabled.addChangeListener { state!!.isEnabled = enabled.isSelected }
line.add(enabled, BorderLayout.WEST)
settings.add(line)
// exclude modules regex
line = JPanel(BorderLayout(5, 5))
line.add(JLabel("Excluded Modules (Regex contains)"), BorderLayout.WEST)
val excludedModules = JTextField()
excludedModules.cursor = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)
excludedModules.text = state!!.getExcludedModules()
excludedModules.document.addDocumentListener(object : DocumentAdapter() {
override fun textChanged(e: DocumentEvent) {
state!!.setExcludedModules(excludedModules.text)
}
})
line.add(excludedModules, BorderLayout.CENTER)
settings.add(line)
// exclude run configurations regex
line = JPanel(BorderLayout(5, 5))
line.add(JLabel("Excluded Run Configurations (Regex contains)"), BorderLayout.WEST)
val excludedRunConfs = JTextField()
excludedRunConfs.cursor = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)
excludedRunConfs.text = state!!.getExcludedRunConfigurations()
excludedRunConfs.document.addDocumentListener(object : DocumentAdapter() {
override fun textChanged(e: DocumentEvent) {
state!!.setExcludedRunConfigurations(excludedRunConfs.text)
}
})
line.add(excludedRunConfs, BorderLayout.CENTER)
settings.add(line)
return container
}

override fun isModified(): Boolean {
return plugin().state != state
}

override fun apply() {
plugin().loadState(state!!)
}

private fun plugin(): ProjectPlugin {
if (plugin == null) {
LOG.error("Plugin is null; that should only happen during indexing")
return ProjectPlugin()
} else {
return plugin
}
}

companion object {
private val LOG = Logger.getInstance(Settings::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.github.jbou.ideaundelegaterun

import com.intellij.execution.Executor
import com.intellij.execution.application.ApplicationConfiguration
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.openapi.project.Project
import com.intellij.task.ExecuteRunConfigurationTask
import org.jetbrains.plugins.gradle.execution.build.GradleExecutionEnvironmentProvider

class UndelegateExecutionEnvironmentProvider : GradleExecutionEnvironmentProvider {
override fun isApplicable(task: ExecuteRunConfigurationTask): Boolean {
if (task.runProfile !is ApplicationConfiguration) {
return false
}
val runProfile = task.runProfile as ApplicationConfiguration
return ProjectPlugin.isEnabledFor(runProfile, runProfile.configurationModule.module)
}

override fun createExecutionEnvironment(
project: Project,
task: ExecuteRunConfigurationTask,
executor: Executor
): ExecutionEnvironment? {
return null
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit c552479

Please sign in to comment.