List a box's own commands, and let them take a per-box name on the host - #238
Open
kacperpaczos wants to merge 3 commits into
Open
List a box's own commands, and let them take a per-box name on the host#238kacperpaczos wants to merge 3 commits into
kacperpaczos wants to merge 3 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.
A tool installed inside a box was invisible in BoxBuddy: the applications list only ever enumerates `.desktop` files, and a command line tool has none. The Applications page now has a Commands section listing what the box itself holds, each with an "Add to Terminal" button that opens the existing add-command dialog with the name filled in. The scan covers `/usr/local/bin` and `/opt/*/bin`, and `$HOME/.local/bin` only when the box has a home of its own - distrobox shares the host's home by default, so scanning it there would list the host's own tools as though they lived in the box. `/usr/bin` is left out: between the base image and distrobox's first-run setup it holds hundreds of entries with nothing to tell a user install apart from them. The add-command dialog gains a "Name on host" field. `distrobox-export` always keeps the command's own name, so a different one can only be a chooser, and a chooser is now written even with nothing in the way - with a single target it runs it without asking. This is what lets the same tool from several boxes sit on the host as separate profiles: `claude` from two boxes becomes `claude-work` and `claude-personal`, each entering its own box. The generated script therefore separates the host-facing name from the command run inside the box, and the marker records both. docs/tips.md explains using a box's own home directory to keep an application's settings and logins separate while the host's files stay reachable, and the new-box form now says the same thing where the choice is actually made.
Four lines of explanation under a form is more than anyone reads. Same three facts - own settings and logins, host files still reachable, exports still land on the host - in one sentence.
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 #237. Builds on #236 (the chooser machinery it reuses); the diff here is only what is new on top of it.
A Commands section
The Applications page lists
.desktopfiles, so a box holding only a command line tool looks empty. There is now a Commands group listing what the box itself has, each row with an Add to Terminal button that opens the add-command dialog with the name filled in.What is scanned is a deliberate choice rather than a guess, and I checked each part on a real machine:
/usr/local/binand/opt/*/bininside the container: container-local, and in practice exactly what was installed by hand.$HOME/.local/binonly when the box has its own home. In a default box that path is the shared host home, so scanning it would list the host's own tools as though they lived in the box - the check is"$HOME" != "${DISTROBOX_HOST_HOME:-$HOME}"./usr/binis left out. A freshly created box already shows 272 added entries there, because distrobox's first-run setup installs a pile of packages; nothing distinguishes a user install from that.A host-side name
distrobox-export --binalways keeps the command's own name, so the same tool in two boxes can only fight over one entry on the host. The dialog gains a Name on host field (blank means "same as the command"). When it differs a chooser is written even with nothing in the way, since export cannot rename - and a chooser with a single target runs it without asking, soclaude-workbehaves like a normal command.That required the generated script to separate two things it used to conflate: the host-facing name (the file, used in messages) and the command run inside the box. The marker records both (
command=and a newcmd=), and the existing# distrobox_binary/# name:markers are unchanged.Documentation
docs/tips.mdgains a section on running the same application under separate profiles: give each box its own home directory, and the box keeps its own settings and logins while the host's files stay reachable and exports still land in the host's menu andPATH(distrobox-exportresolveshost_homefromDISTROBOX_HOST_HOME, verified). The new-box form now explains the Home Directory field where the choice is actually made, instead of leaving it as a bare path input.Screenshots
Testing
cargo test: 22 pass (4 new - the scan's parsing keeps one entry per name and dropsfind's error lines, relative junk and names that fail validation; the generated script runs the in-box command under its host name; the menu is guarded by the target count).End to end on a virtual display with an isolated
$HOMEand a stubdistrobox: the Commands section lists what the stub reports; addingclaudeasclaude-pracawrites a chooser whose marker readscommand=claude-praca cmd=claude, and running it - through a pipe and through a pty - goes straight todistrobox enter second -- claudewith no prompt. Adding the same host name from a second box merges it (boxes=second,fakebox, a# name:line each), and the pty run then shows the menu and dispatches to the chosen box.One limitation I did not hide: a chooser holds one in-box command for all its targets, so boxes where the tool has different names would need separate host names. Say the word and I will make
cmd=per target instead.