Add a box command to the host terminal, with a host/box chooser - #236
Open
kacperpaczos wants to merge 2 commits into
Open
Add a box command to the host terminal, with a host/box chooser#236kacperpaczos wants to merge 2 commits into
kacperpaczos wants to merge 2 commits into
Conversation
BoxBuddy could export an application to the host menu, but not a command to the host terminal, and a command that exists both on the host and in a box could only shadow one with the other. The Exported Binaries section gains an "Add Command…" button. The command is resolved inside the box first; if nothing on the host answers to that name it is a plain `distrobox-export --bin`, exactly as before. When the host already has one - its own binary, an earlier distrobox export, or a chooser BoxBuddy wrote before - the dialog offers to replace it with a chooser: a small self-contained bash script in ~/.local/bin that asks, at invocation time, which one to run. The chooser prints a numbered menu on stderr and reads the answer from /dev/tty, so it never eats the program's own stdin. Scripts and pipes must not block on a prompt, so with no terminal it runs the first target silently, and BOXBUDDY_DISPATCH=host|<box> picks one outright. Adding the same command from another box folds that box into the existing chooser rather than replacing it. The file carries distrobox's own `# distrobox_binary` and `# name: <box>` markers next to BoxBuddy's, so `distrobox-export --list-binaries` still finds the command and `--delete` still removes it; without them distrobox would quietly lose sight of a command it had exported. The binaries list skips entries that are choosers so they are not listed twice. Nothing else knows about the chooser: the file is the whole state, and it keeps working if BoxBuddy is uninstalled.
`make lint` runs clippy, and the strings added here tripped needless_borrows_for_generic_args - gettext takes anything that converts into a String, so the format! result can go in as it is. Only the lines this branch introduced are touched; the same pattern elsewhere in the file predates it and is left alone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #235
Adds an Add Command… button to the Exported Binaries section, so a command from a box can be made available in the host terminal - and when the host already has one under that name, the two can coexist behind a chooser instead of one shadowing the other.
The flow
command -vinside it). Not there → a "Not Found" popup, nothing is written.distrobox-export --bin. Unchanged distrobox behaviour, no new concepts, and the new row appears in the list straight away.in box <name>for an existing export) and offers Replace With Chooser. On confirm the targets are merged - an existing chooser's boxes, the box of a distrobox wrapper, and the box you are in - and one chooser is written.The chooser
A self-contained bash script in
~/.local/bin, generated from one template so every one of them has the same shape:/dev/tty, so it never consumes the program's own stdin..desktoplauncher) it does not prompt - it runs the first target. A prompt there would hang every script that calls the command.BOXBUDDY_DISPATCH=host|<box>picks a target outright, for scripts that want a specific one.Nothing else knows about it: the file is the entire state. No config, no database, and it keeps working after BoxBuddy is uninstalled.
Staying visible to distrobox
distrobox-exportkeeps no registry - the state is two comment lines in the file it writes,# distrobox_binaryand# name: <container>.list_exported_binariesgreps for the first and filters on the second, and--deleterefuses with "is not exported" when the first is absent. A chooser overwriting an exported wrapper would therefore make distrobox lose sight of the command silently.So the chooser carries those two markers (one
# name:line per target box) next to BoxBuddy's own.--list-binariesfrom any target box still finds it,--deletestill removes it, and the two tools agree. This is the one thing in the PR I would flag for a veto - it is BoxBuddy writing distrobox's markers into a file distrobox did not generate. The alternative is that the command quietly disappears from--list-binaries; I thought agreement was the lesser evil, but it is your call. As a consequence the binaries list skips entries that are choosers, so a command is not listed twice.Screenshots
Virtual display, stub
distrobox, isolated$HOME- a fakeclaudeon the host andclaudein the box.The chooser row afterwards, and the same dialog when what is in the way is an earlier distrobox export:
Testing
cargo test: 18 pass (12 new), covering the script/marker round-trip, the command-name validation,bash -non every shape of generated script, the realdistrobox-exportwrapper text parsed back to its container name, and a behavioural test that runs a generated chooser against a stubdistroboxand asserts what it exec'd.End to end on a virtual display with an isolated
$HOME, a stubdistroboxand a fake host binary, driving the real UI: plain export, conflict → chooser, the chooser listed after reopening the window, and re-adding a command that is already a distrobox export. The generated file was then run for real - through a pty for the menu (choice, empty input, out-of-range), through a pipe for the no-terminal path, and withBOXBUDDY_DISPATCHset to a box, tohost, and to a bad value (exit 2).Two limits I did not paper over: a box literally named
hostwould be shadowed by the host entry, and a host path containing whitespace cannot round-trip through the marker line (runtime quoting is unaffected). Both are noted in the code.The Flatpak path goes through the existing
run_command/get_command_outputhelpers, so the host is reached withflatpak-spawn --host; I could only test the native path here.