feat: added eval option - #384
Conversation
|
Thanks for the PR, can you share your thoughts on this issue? |
7a0f1fb to
44805ed
Compare
3216768 to
f33ea2f
Compare
|
@lotheac Lauri, hi, what do you think about this one? |
sorry, took me a long time to get to this. IMHO, we should not do this. In my view, it is a design decision that kubie only supports new shells -- it makes each session cleanly contained, and gives it a place to properly clean up on shell exit -- as you've noticed, removing the kubeconfigs becomes difficult if you don't know when the kubie session terminates. @pasteley can you elaborate on why you want this? Is there some specific use case that cannot be supported otherwise? |
|
Specifically on the subject of shell keybindings: I don't see why a keybinding for switching context would not work, as long as you are already in a kubie shell. Unless I'm missing something. |
|
@lotheac Thought I'd chime in on this one since I think it should fix an issue I'm seeing when using kubie. In my case, spawning a new shell isn't ideal, because that confuses the zsh command history. As soon as I close the shell, I lose the commands I executed. Maybe this can be fixed via some config setting in zsh, but kubie is the only CLI app I use which has this issue. Otherwise, it works great! |
Signed-off-by: pasteley <ceasebeing@gmail.com>
I don't think that's actually holds in the codebase, we had this: if vars::is_kubie_active() && !recursive {
let path = kubeconfig::get_kubeconfig_path()?;
kubeconfig.write_to_file(path.as_path())?;
session.save(None)?;
} else {
spawn_shell(settings, kubeconfig, &session)?;
}Which mean when you're already inside an active kubie session and switch context without I actually tried building the keybinding without On the implementation itself: it's opt-in, so nothing changes unless you pass the flag, and it uses its own temp file naming ( One thing worth flagging myself: kubie's temp files normally clean up because it waits on the spawned shell and deletes them on exit. |
|
On Sat, Aug 08 2026 04:32:34 -0700, Pasteley Absurda wrote:
pasteley left a comment (kubie-org/kubie#384)
@lotheac
> kubie only supports new shells point
I don't think that's actually holds in the codebase, we had this:
```rust
if vars::is_kubie_active() && !recursive {
let path = kubeconfig::get_kubeconfig_path()?;
kubeconfig.write_to_file(path.as_path())?;
session.save(None)?;
} else {
spawn_shell(settings, kubeconfig, &session)?;
}
```
Which mean when you're already inside an active kubie session and switch context without `-r`, kubie just rewrites the kubeconfig file in place without spawning new shell. `--eval` is the same idea applied one step earlier: before you're inside a kubie shell, so there's no existing file to rewrite, you set env vars in the calling shell instead. (this PR pulls that inline check into the `ActivationMode` enum in `activation.rs` and adds `Eval` as a third option alongside it)
Hard disagree. "one step earlier" is doing a lot of work there -- it
entirely changes what kubie has to be responsible for. It is
one thing for kubie to do something when it knows it is its own child
process, but a very different thing for it be a bunch of shell code to
be injected into anything.
I actually tried building the keybinding without `--eval` first, and it doesn't work at all. `spawn_shell` (`shell/zsh.rs:141-146`) doesn't redirect the new shell's output, it inherits whatever the parent has. A keybinding has to call kubie through `output=$(kubie ctx ...)` to capture anything, which means stdout is a pipe, not the terminal, so the second you spawn a shell that way, its whole session (prompt, output, everything) goes into that pipe instead of the screen.
On the implementation itself: it's opt-in, so nothing changes unless you pass the flag, and it uses its own temp file naming (`kubie-eval-*`) so it can't collide with the regular spawn flow's files (tested for that too). Repeated `--eval` calls in the same session reuse the same files instead of piling up new ones.
One thing worth flagging myself: kubie's temp files normally clean up because it waits on the spawned shell and deletes them on exit. `--eval` prints and exits immediately, so there's no automatic cleanup -> files sit until reused or cleared by the OS. Same tradeoff tools likes direnv and zoxide live with, so I don't see it as a blocker.
I'm sorry, @pasteley, but I can not understand what you are saying here.
"One thing worth flagging myself" stinks of LLMs. I'm sorry that I have
to ask, but am I talking to a human?
…--
Lauri Tirkkonen | lotheac @ IRCnet
|
|
@lotheac The output isn't shell code though, it's 5 env vars, no hooks, no functions, no logic. Idea is basically copied from direnv, where subprocess computes the diff and caller applies it. So "injected into anything" doesn't really describe what's printed here.
Just wording, may be the case of llm corrupting language, but mentioned it because found it while playing around with this feature.
As I mentioned in description, activating kubie via keybinding from a shell that isn't already a kubie session is exactly such use case, there's no other way to get a context/namespace switch back into the calling shell. I couldn't manage to make ZLE widget to spawn an interactive child without breaking the terminal, nested shell's output just gets swallowed into the capture pipe. |
|
@pasteley A big part of the reason why I started using kubie initially, instead of alternatives, is because the subprocess design is clean: you can go back to kubie-less state by just exiting the shell, no temp files are leaked. It is a design decision for it to work this way, and adding --eval is an escape hatch from that design -- that's why I'm arguing against it. To be clear, I'm not against improving user experience with respect to keybindings, but I don't think --eval is a good tradeoff. Using --eval makes kubie semantically a shell code generator instead of a shell wrapper, which means its responsibilities change: from "modify environ, run subprocess, wait for it to exit, clean up" to: "create temp file, generate shell-specific code to set env vars, hope someone else cleans up". I realize kubie already does emit shell code for the prompt modifications etc. However, if anything goes wrong there, the shell that ran kubie is unaffected -- unlike when using Also, as your implementation shows, the emitted code needs to be shell-specific. kubie already requires a supported shell, but you've only implemented --eval for a subset of those supported shells. As an alternative, what if you had a shell keybinding that clears the input line, types in "kubie ctx" and runs it? That way you keep all the benefits of the subshell, with its cleanups and ability to return to a kubie-less shell. As an additional improvement, you could detect in the keybinding whether you're in a kubie shell, and if so, no need to touch the input line. BTW, have you considered |
Closes: #85 #371
This PR os also a prerequisite for #378 — shell keybindings to activate a context in the current shell
Summary
kubie always spawn a new shell (or switch in-place inside an existing kubie shell). This makes it impossible to use it from shell keybindings or wrapper functions, there's no way to set
KUBECONFIGin the current shell without spawning a subshell.Added
--evalflag solves this by printing export statements to stdout instead of spawning a shell like this:eval "$(kubie ctx --eval my-context)"This reflects pattern used by tools like direnv, fzf, and zoxide.
What changed
kubie ctx --eval/kubie ns --eval— writes temp kubeconfig and session files, then emits shell export statements (bash/zsh/fish) to stdout. The caller evals the output to activate the context in the current shellActivationModeenum replaces therecursive: boolparameter, centralizing the spawn/switch/eval decision in one placestdout.is_terminal()tostdin.is_terminal()$(...), stdout is captured (not a tty), so kubie would list contexts instead of showing the interactive selector.--evalinvocation to avoid leaking files in /tmp