Skip to content
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

feat: Introduce Mise Toml Task Run Configuration #129

Merged
merged 2 commits into from
Jan 5, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.github.l34130.mise.core.execution.configuration

import com.github.l34130.mise.core.setting.MiseSettings
import com.intellij.execution.Executor
import com.intellij.execution.configuration.EnvironmentVariablesData
import com.intellij.execution.configurations.CommandLineState
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.configurations.LocatableConfigurationBase
import com.intellij.execution.configurations.RunConfiguration
import com.intellij.execution.configurations.RunProfileState
import com.intellij.execution.process.ColoredProcessHandler
import com.intellij.execution.process.ProcessHandler
import com.intellij.execution.process.ProcessTerminatedListener
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.components.service
import com.intellij.openapi.options.SettingsEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.encoding.EncodingManager
import com.intellij.util.EnvironmentUtil
import com.intellij.util.application
import org.jdom.Element

class MiseTomlTaskRunConfiguration(
project: Project,
factory: MiseTomlTaskRunConfigurationFactory,
name: String,
) : LocatableConfigurationBase<RunProfileState>(project, factory, name) {
private val settings = application.service<MiseSettings>().state

var miseExecutablePath: String = settings.executablePath
var miseConfigEnvironment: String? = settings.miseConfigEnvironment
var miseTaskName: String = ""
var workingDirectory: String? = project.basePath
var envVars: EnvironmentVariablesData = EnvironmentVariablesData.DEFAULT

override fun getState(
executor: Executor,
executionEnvironment: ExecutionEnvironment,
): RunProfileState {
return object : CommandLineState(executionEnvironment) {
override fun startProcess(): ProcessHandler {
val macroManager = PathMacroManager.getInstance(project)
val workDirectory =
workingDirectory?.let { macroManager.expandPath(it) }
?: project.basePath

val params = mutableListOf<String>()
miseConfigEnvironment?.let {
params += listOf("--env", it)
}
params += listOf("run", miseTaskName)

val commandLine =
GeneralCommandLine()
.withExePath(miseExecutablePath)
.withWorkDirectory(workDirectory)
.withEnvironment(EnvironmentUtil.getEnvironmentMap() + envVars.envs)
.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE)
.withParameters(params)
.withCharset(EncodingManager.getInstance().defaultConsoleEncoding)

return ColoredProcessHandler(commandLine).apply {
setShouldKillProcessSoftly(true)
ProcessTerminatedListener.attach(this)
}
}
}
}

override fun getConfigurationEditor(): SettingsEditor<out RunConfiguration> = MiseTomlTaskRunConfigurationEditor(project)

override fun writeExternal(element: Element) {
super.writeExternal(element)
val child = element.getOrCreateChild("mise")
child.setAttribute("executablePath", miseExecutablePath)
child.setAttribute("configEnvironment", miseConfigEnvironment ?: "")
child.setAttribute("taskName", miseTaskName)
child.setAttribute("workingDirectory", workingDirectory ?: "")
envVars.writeExternal(child)
}

override fun readExternal(element: Element) {
super.readExternal(element)
val child = element.getChild("mise") ?: return
miseExecutablePath = child.getAttributeValue("executablePath") ?: ""
miseConfigEnvironment = child.getAttributeValue("configEnvironment")
miseTaskName = child.getAttributeValue("taskName") ?: ""
workingDirectory = child.getAttributeValue("workingDirectory")
envVars = EnvironmentVariablesData.readExternal(child)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.github.l34130.mise.core.execution.configuration

import com.github.l34130.mise.core.lang.MiseTomlFileType
import com.github.l34130.mise.core.setting.MiseSettings
import com.intellij.execution.configuration.EnvironmentVariablesComponent
import com.intellij.openapi.components.service
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
import com.intellij.openapi.options.SettingsEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.TextFieldWithBrowseButton
import com.intellij.ui.components.JBTextField
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.panel
import com.intellij.util.application
import com.intellij.util.ui.JBUI
import javax.swing.JComponent

class MiseTomlTaskRunConfigurationEditor(
private val project: Project,

Check warning on line 19 in modules/core/src/main/kotlin/com/github/l34130/mise/core/execution/configuration/MiseTomlTaskRunConfigurationEditor.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Constructor parameter is never used as a property

Constructor parameter is never used as a property
) : SettingsEditor<MiseTomlTaskRunConfiguration>() {
private val applicationState = application.service<MiseSettings>().state

Check warning on line 21 in modules/core/src/main/kotlin/com/github/l34130/mise/core/execution/configuration/MiseTomlTaskRunConfigurationEditor.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "applicationState" is never used

private val miseExecutablePathTf = TextFieldWithBrowseButton()
private val miseConfigEnvironmentTf = JBTextField()
private val miseTaskNameTf = JBTextField()
private val workingDirectoryTf = TextFieldWithBrowseButton()
private val envVarsComponent = EnvironmentVariablesComponent()

init {
miseExecutablePathTf.addBrowseFolderListener(
"Mise Executable Path",
"Select the Mise executable path",
project,
FileChooserDescriptorFactory.createSingleFileDescriptor(MiseTomlFileType),
)
workingDirectoryTf.addBrowseFolderListener(
"Working Directory",
"Select the working directory",
project,
FileChooserDescriptorFactory.createSingleFolderDescriptor(),
)
}

override fun createEditor(): JComponent =
panel {
row("Mise executable:") {
cell(miseExecutablePathTf).align(AlignX.FILL)
}
row("Mise config environment:") {
cell(miseConfigEnvironmentTf).align(AlignX.FILL)
}
row("Mise task name:") {
cell(miseTaskNameTf).align(AlignX.FILL)
}
row("Working directory:") {
cell(workingDirectoryTf).align(AlignX.FILL)
}
row("Environment variables:") {
cell(envVarsComponent).align(AlignX.FILL)
}
}.apply {
border = JBUI.Borders.empty(6, 16, 16, 16)
}

override fun resetEditorFrom(configuration: MiseTomlTaskRunConfiguration) {
miseExecutablePathTf.text = configuration.miseExecutablePath
miseConfigEnvironmentTf.text = configuration.miseConfigEnvironment
miseTaskNameTf.text = configuration.miseTaskName
workingDirectoryTf.text = configuration.workingDirectory ?: ""
envVarsComponent.envData = configuration.envVars
}

override fun applyEditorTo(configuration: MiseTomlTaskRunConfiguration) {
configuration.miseExecutablePath = miseExecutablePathTf.text
configuration.miseConfigEnvironment = miseConfigEnvironmentTf.text
configuration.miseTaskName = miseTaskNameTf.text
configuration.workingDirectory = workingDirectoryTf.text
configuration.envVars = envVarsComponent.envData
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.github.l34130.mise.core.execution.configuration

import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.configurations.RunConfiguration
import com.intellij.openapi.project.Project
import org.toml.lang.psi.TomlKeySegment

class MiseTomlTaskRunConfigurationFactory(
private val runConfigurationType: MiseTomlTaskRunConfigurationType,

Check warning on line 9 in modules/core/src/main/kotlin/com/github/l34130/mise/core/execution/configuration/MiseTomlTaskRunConfigurationFactory.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Constructor parameter is never used as a property

Constructor parameter is never used as a property
) : ConfigurationFactory(runConfigurationType) {
override fun getId(): String = "MiseTomlTask"

override fun getName(): String = "Mise Toml Task"

override fun createTemplateConfiguration(project: Project): RunConfiguration = MiseTomlTaskRunConfiguration(project, this, "name")

fun createConfigurationFromMiseTomlTask(segment: TomlKeySegment): MiseTomlTaskRunConfiguration? {

Check warning on line 17 in modules/core/src/main/kotlin/com/github/l34130/mise/core/execution/configuration/MiseTomlTaskRunConfigurationFactory.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Function "createConfigurationFromMiseTomlTask" is never used
TODO()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.github.l34130.mise.core.execution.configuration

import com.github.l34130.mise.core.lang.psi.MiseTomlFile
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.LazyRunConfigurationProducer
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement

class MiseTomlTaskRunConfigurationProducer : LazyRunConfigurationProducer<MiseTomlTaskRunConfiguration>() {
override fun getConfigurationFactory(): ConfigurationFactory =
MiseTomlTaskRunConfigurationFactory(MiseTomlTaskRunConfigurationType.getInstance())

override fun isConfigurationFromContext(
configuration: MiseTomlTaskRunConfiguration,
context: ConfigurationContext,
): Boolean {
val macroManager = PathMacroManager.getInstance(context.project)
// return macroManager.expandPath(configuration.filename) == context.location?.virtualFile?.path &&
// configuration.target == findTarget(context)?.name

return true
}

override fun setupConfigurationFromContext(
configuration: MiseTomlTaskRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>,
): Boolean {
if (context.psiLocation?.containingFile !is MiseTomlFile) return false

val macroManager = PathMacroManager.getInstance(context.project)
val path = context.location?.virtualFile?.path

// edit configuration

return true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.github.l34130.mise.core.execution.configuration

import com.github.l34130.mise.core.icon.MiseIcons
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.configurations.ConfigurationType
import com.intellij.execution.configurations.ConfigurationTypeUtil
import javax.swing.Icon

class MiseTomlTaskRunConfigurationType : ConfigurationType {
override fun getDisplayName(): String = "Mise Toml Task"

override fun getConfigurationTypeDescription(): String = "Mise Toml Task run configuration"

override fun getIcon(): Icon = MiseIcons.DEFAULT

override fun getId(): String = javaClass.simpleName

override fun getConfigurationFactories(): Array<ConfigurationFactory> = arrayOf(MiseTomlTaskRunConfigurationFactory(this))

companion object {
fun getInstance(): MiseTomlTaskRunConfigurationType =
ConfigurationTypeUtil.findConfigurationType(MiseTomlTaskRunConfigurationType::class.java)
}
}
6 changes: 6 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
<JsonSchema.ProviderFactory order="first" implementation="com.github.l34130.mise.core.lang.json.MiseTomlJsonSchemaFileProviderFactory"/>
</extensions>

<!-- Execution Support -->
<extensions defaultExtensionNs="com.intellij">
<configurationType implementation="com.github.l34130.mise.core.execution.configuration.MiseTomlTaskRunConfigurationType"/>
<runConfigurationProducer implementation="com.github.l34130.mise.core.execution.configuration.MiseTomlTaskRunConfigurationProducer"/>
</extensions>

<extensions defaultExtensionNs="com.intellij">
<projectConfigurable id="com.github.l34130.mise.core.setting.MiseConfigurable"
instance="com.github.l34130.mise.core.setting.MiseConfigurable"
Expand Down
Loading