commit - 513258b76f2bcdaf8deeca03c0f1745660bd13b4
commit + e508740b86451a34024db9d279843f7168c3df94
blob - 51c15a60b3fe0cd0d8c4f69086f6ebdada80525d
blob + 8c7b07b8439c7003f455c3e811f58ce6df93e266
--- src/main/kotlin/dev/nezzontli/gotvcs/GotCommandLineWrapper.kt
+++ src/main/kotlin/dev/nezzontli/gotvcs/GotCommandLineWrapper.kt
data class GotUpdateEntry(val code: Char, val path: String)
/**
- * Centraliza todas las invocaciones al binario `got`. La ruta de abajo es la
- * del store de Nix resuelta al momento de escribir este código
- * (readlink -f /etc/profiles/per-user/ale/bin/idea muestra el store path del
- * IDE; el de got se resolvió igual desde /run/current-system/sw/bin/got).
- * Cambia con cada rebuild del sistema -> deuda para GotConfigurable (Fase 6).
+ * Centraliza todas las invocaciones al binario `got`. Ruta al binario y
+ * SSH_AUTH_SOCK son configurables en Settings > Version Control > got
+ * (GotConfigurable/GotSettingsState); si no se configuran, caen a detección
+ * automática -- ver binaryPath()/sshAuthSock().
*/
class GotCommandLineWrapper {
private fun binaryPath(): String {
+ GotSettingsState.getInstance().gotBinaryPath.takeIf { it.isNotBlank() }?.let { return it }
val nixPath = File("/run/current-system/sw/bin/got")
return if (nixPath.canExecute()) nixPath.path else "got"
}
* IntelliJ mismo (System.getenv, no solo el snapshot cacheado de
* GeneralCommandLine) según cómo Hyprland lo haya lanzado esa sesión --
* no es algo que este plugin pueda forzar si el valor real no existe.
- * Fallback a la ruta fija del socket ssh de gpg-agent en este sistema
- * (uid 1000, único usuario). Igual que la ruta de `got`, debería ser
- * configurable en la Fase 6 en vez de estar fija.
+ * Fallback: override manual en Settings, y si tampoco está seteado, la
+ * ruta fija del socket ssh de gpg-agent en este sistema (uid 1000,
+ * único usuario).
*/
private fun sshAuthSock(): String? {
+ GotSettingsState.getInstance().sshAuthSock.takeIf { it.isNotBlank() }?.let { return it }
System.getenv("SSH_AUTH_SOCK")?.let { return it }
val fallback = File("/run/user/1000/gnupg/S.gpg-agent.ssh")
return if (fallback.exists()) fallback.path else null
.withWorkDirectory(workDir)
.withCharset(StandardCharsets.UTF_8)
.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.SYSTEM)
- val sshAuthSock = sshAuthSock()
- sshAuthSock?.let { commandLine.environment["SSH_AUTH_SOCK"] = it }
+ sshAuthSock()?.let { commandLine.environment["SSH_AUTH_SOCK"] = it }
val output = try {
ExecUtil.execAndGetOutput(commandLine)
} catch (e: ExecutionException) {
throw VcsException("No se pudo ejecutar got ${args.joinToString(" ")}: ${e.message}", e)
}
if (output.exitCode != 0) {
- throw VcsException(
- "got ${args.joinToString(" ")} salió con código ${output.exitCode}: " +
- "${output.stderr.trim()} [SSH_AUTH_SOCK=$sshAuthSock]"
- )
+ throw VcsException("got ${args.joinToString(" ")} salió con código ${output.exitCode}: ${output.stderr.trim()}")
}
return output.stdout
}
blob - /dev/null
blob + 01e778b4cc412bea174886428b1f9c07e63e7ae4 (mode 644)
--- /dev/null
+++ src/main/kotlin/dev/nezzontli/gotvcs/GotConfigurable.kt
+package dev.nezzontli.gotvcs
+
+import com.intellij.openapi.options.Configurable
+import com.intellij.openapi.ui.TextFieldWithBrowseButton
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
+import com.intellij.util.ui.FormBuilder
+import javax.swing.JComponent
+import javax.swing.JPanel
+import javax.swing.JTextField
+
+class GotConfigurable : Configurable {
+
+ private var panel: JPanel? = null
+ private var gotBinaryField: TextFieldWithBrowseButton? = null
+ private var sshAuthSockField: JTextField? = null
+
+ override fun getDisplayName(): String = "got"
+
+ override fun createComponent(): JComponent {
+ val binaryField = TextFieldWithBrowseButton().apply {
+ addBrowseFolderListener(
+ "Ruta al binario got",
+ "Vacío para detectarlo automáticamente (/run/current-system/sw/bin/got o PATH)",
+ null,
+ FileChooserDescriptorFactory.createSingleFileDescriptor(),
+ )
+ }
+ val sockField = JTextField()
+
+ gotBinaryField = binaryField
+ sshAuthSockField = sockField
+
+ val built = FormBuilder.createFormBuilder()
+ .addLabeledComponent("Binario got:", binaryField)
+ .addTooltip("Vacío para detectarlo automáticamente (/run/current-system/sw/bin/got o PATH)")
+ .addLabeledComponent("SSH_AUTH_SOCK:", sockField)
+ .addTooltip("Vacío para usar el del proceso de IntelliJ, con fallback a /run/user/<uid>/gnupg/S.gpg-agent.ssh")
+ .addComponentFillVertically(JPanel(), 0)
+ .panel
+
+ panel = built
+ reset()
+ return built
+ }
+
+ override fun isModified(): Boolean {
+ val settings = GotSettingsState.getInstance()
+ return gotBinaryField?.text.orEmpty() != settings.gotBinaryPath ||
+ sshAuthSockField?.text.orEmpty() != settings.sshAuthSock
+ }
+
+ override fun apply() {
+ val settings = GotSettingsState.getInstance()
+ settings.gotBinaryPath = gotBinaryField?.text.orEmpty()
+ settings.sshAuthSock = sshAuthSockField?.text.orEmpty()
+ }
+
+ override fun reset() {
+ val settings = GotSettingsState.getInstance()
+ gotBinaryField?.text = settings.gotBinaryPath
+ sshAuthSockField?.text = settings.sshAuthSock
+ }
+
+ override fun disposeUIResources() {
+ panel = null
+ gotBinaryField = null
+ sshAuthSockField = null
+ }
+}
blob - /dev/null
blob + 59f56f981c62253964510e70eb413f50399c20c0 (mode 644)
--- /dev/null
+++ src/main/kotlin/dev/nezzontli/gotvcs/GotSettingsState.kt
+package dev.nezzontli.gotvcs
+
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.components.PersistentStateComponent
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+import com.intellij.util.xmlb.XmlSerializerUtil
+
+/**
+ * Rutas configurables desde Settings > Version Control > got. Vacío ("")
+ * significa "usar la detección automática" (ver GotCommandLineWrapper):
+ * binario got en /run/current-system/sw/bin/got o PATH, y SSH_AUTH_SOCK de
+ * System.getenv() o el socket fijo de gpg-agent.
+ */
+@State(name = "GotVcsSettings", storages = [Storage("gotvcs.xml")])
+class GotSettingsState : PersistentStateComponent<GotSettingsState> {
+
+ var gotBinaryPath: String = ""
+ var sshAuthSock: String = ""
+
+ override fun getState(): GotSettingsState = this
+
+ override fun loadState(state: GotSettingsState) {
+ XmlSerializerUtil.copyBean(state, this)
+ }
+
+ companion object {
+ @JvmStatic
+ fun getInstance(): GotSettingsState =
+ ApplicationManager.getApplication().getService(GotSettingsState::class.java)
+ }
+}
blob - 7691b318ffa7f5dfcd4c30985ff5418261cd2591
blob + 43cc025a25cf34f1f1fa2383094d5b56a5a9b582
--- src/main/resources/META-INF/plugin.xml
+++ src/main/resources/META-INF/plugin.xml
displayName="got"
administrativeAreaName=".got"/>
<vcsRootChecker implementation="dev.nezzontli.gotvcs.GotVcsRootChecker"/>
+ <applicationService serviceImplementation="dev.nezzontli.gotvcs.GotSettingsState"/>
+ <applicationConfigurable instance="dev.nezzontli.gotvcs.GotConfigurable" displayName="got" parentId="vcs"/>
</extensions>
</idea-plugin>