Skip to content

Commit

Permalink
Add settings page to allow configuration of rpm executable path
Browse files Browse the repository at this point in the history
Currently if the path is changed the IDE needs to be restarted to pick
up the changes.
  • Loading branch information
tlusk committed Jan 21, 2021
1 parent 8889ed4 commit 1ec53eb
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.carbonblack.intellij.rpmmacro

import com.carbonblack.intellij.rpmmacro.psi.RpmMacroFile
import com.carbonblack.intellij.rpmmacro.psi.RpmMacroMacro
import com.carbonblack.intellij.rpmspec.RpmSpecSettingsState
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
Expand All @@ -25,10 +26,9 @@ import kotlin.streams.asSequence

private val log = Logger.getInstance(RpmMacroUtil::class.java)

private fun String.runCommand(workingDir: File? = null, action: (String) -> Unit) {
val parts = this.split("\\s".toRegex())
private fun List<String>.runCommand(workingDir: File? = null, action: (String) -> Unit) {
val proc = ProcessBuilder()
.command(parts)
.command(this)
.directory(workingDir)
.redirectErrorStream(true)
.start()
Expand Down Expand Up @@ -92,7 +92,7 @@ object RpmMacroUtil {

val pathsRegex = Regex("^Macro path: (.*)$")
val targetRegex = Regex("^\\S+:\\s+_target\\s+(.*)$")
"rpm --showrc".runCommand { line ->
listOf(RpmSpecSettingsState.instance.rpmCommandPath, "--showrc").runCommand { line ->
if (paths.isEmpty()) {
pathsRegex.find(line)?.groups?.get(1)?.let { match ->
paths += match.value.split(":")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.carbonblack.intellij.rpmspec

import com.carbonblack.intellij.rpmmacro.RpmMacroUtil
import com.intellij.openapi.options.Configurable
import com.intellij.ui.IdeBorderFactory
import com.intellij.ui.components.JBList
import com.intellij.ui.components.JBScrollPane
import com.intellij.ui.components.JBTextField
import com.intellij.util.ui.FormBuilder
import java.awt.BorderLayout
import java.awt.Insets
import javax.swing.*
import kotlin.reflect.KProperty

private class TextFieldDelegate(private val textField: JBTextField) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return textField.text
}

operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
textField.text = value
}
}

class RpmSpecSettingsConfigurable : Configurable {
override fun getDisplayName() = "RPM SPEC File"
override fun getPreferredFocusedComponent(): JComponent = rpmCommandPathBox

private val rpmCommandPathBox = JBTextField("rpm")
private var rpmCommandPath: String by TextFieldDelegate(rpmCommandPathBox)

private val detectedPathsList = JBList<String>().apply {
selectionMode = ListSelectionModel.SINGLE_SELECTION
border = IdeBorderFactory.createEmptyBorder(Insets(0, 3, 0, 0))
isFocusable = false
}

override fun createComponent(): JComponent {
val detectedMacrosPanel = JPanel(BorderLayout()).apply {
// This is for if we decide to make the list of macros editable
/* val toolbarDecorator = ToolbarDecorator.createDecorator(detectedPathsList)
.setScrollPaneBorder(JBUI.Borders.empty())
.setPanelBorder(JBUI.Borders.customLine(JBColor.border(), 0, 1, 0, 1))
add(toolbarDecorator.createPanel(), BorderLayout.NORTH) */
add(JBScrollPane(detectedPathsList), BorderLayout.CENTER)
border = IdeBorderFactory.createTitledBorder("Detected Macro Files:", false).setShowLine(false)
}

return FormBuilder.createFormBuilder()
.addLabeledComponent("Path to rpm executable:", rpmCommandPathBox)
.addComponentFillVertically(detectedMacrosPanel, 12)
.panel
}

override fun isModified(): Boolean {
return rpmCommandPath != RpmSpecSettingsState.instance.rpmCommandPath
}

override fun apply() {
RpmSpecSettingsState.instance.rpmCommandPath = rpmCommandPath
}

override fun reset() {
rpmCommandPath = RpmSpecSettingsState.instance.rpmCommandPath
detectedPathsList.setListData(RpmMacroUtil.macroPathFiles.mapNotNull { it.canonicalPath }.toTypedArray())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.carbonblack.intellij.rpmspec

import com.carbonblack.intellij.rpmmacro.RpmMacroUtil
import com.intellij.openapi.components.*
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.io.exists
import com.intellij.util.xmlb.XmlSerializerUtil
import java.io.File
import java.nio.file.Paths

private val log = Logger.getInstance(RpmMacroUtil::class.java)

@State(name = "RpmSpecSettings", storages = [Storage("rpmSpec.xml")])
class RpmSpecSettingsState : PersistentStateComponent<RpmSpecSettingsState> {
var rpmCommandPath = findRpmPath() ?: "rpm"

override fun getState(): RpmSpecSettingsState = this
override fun loadState(state: RpmSpecSettingsState) {
XmlSerializerUtil.copyBean(state, this)
}

companion object {
val instance: RpmSpecSettingsState
get() = ServiceManager.getService(RpmSpecSettingsState::class.java)

private fun findRpmPath(): String? {
return try {
System.getenv().getOrDefault("PATH", "")
.split(File.pathSeparator)
.map { Paths.get(it).resolve("rpm") }
.find { it.exists() }
?.toAbsolutePath()
?.toString()
} catch (e: Exception) {
log.warn("Error trying to find rpm executable.", e)
null
}
}
}
}
4 changes: 4 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
<annotator language="RpmSpec" implementationClass="com.carbonblack.intellij.rpmspec.RpmSpecHighlightingAnnotator"/>
<lang.braceMatcher language="RpmSpec" implementationClass="com.carbonblack.intellij.rpmspec.RpmSpecBraceMatcher"/>
<lang.psiStructureViewFactory language="RpmSpec" implementationClass="com.carbonblack.intellij.rpmspec.RpmSpecStructureViewFactory"/>
<applicationService serviceImplementation="com.carbonblack.intellij.rpmspec.RpmSpecSettingsState"/>
<applicationConfigurable parentId="tools" instance="com.carbonblack.intellij.rpmspec.RpmSpecSettingsConfigurable"
id="com.carbonblack.intellij.rpmspec.RpmSpecSettingsConfigurable"
displayName="RPM SPEC File"/>
</extensions>

<!-- RPM Macro File -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.carbonblack.intellij.rpmmacro

import com.carbonblack.intellij.rpmspec.RpmSpecSettingsState
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import io.mockk.clearAllMocks
import io.mockk.every
Expand Down Expand Up @@ -70,7 +71,9 @@ class RpmMacroUtilTest : BasePlatformTestCase() {
clearAllMocks()

mockkConstructor(ProcessBuilder::class)
every { anyConstructed<ProcessBuilder>().command(listOf("rpm", "--showrc")) } answers {
every {
anyConstructed<ProcessBuilder>().command(listOf(RpmSpecSettingsState.instance.rpmCommandPath, "--showrc"))
} answers {
(callOriginal()).command("unknown-command")
}

Expand Down

0 comments on commit 1ec53eb

Please sign in to comment.