Skip to content

Show which profile a box is on, and create profiles from the new-box form - #241

Open
kacperpaczos wants to merge 3 commits into
Dvlv:masterfrom
kacperpaczos:feat/profile-info
Open

Show which profile a box is on, and create profiles from the new-box form#241
kacperpaczos wants to merge 3 commits into
Dvlv:masterfrom
kacperpaczos:feat/profile-info

Conversation

@kacperpaczos

Copy link
Copy Markdown
Contributor

Follows #239 (profiles) and #240 (cloning onto one). Two gaps that showed up as soon as profiles existed.

A box did not say which profile it was on

Once a box is built, the thing a profile decides - which home it uses - was invisible. Its page now starts with a Profile row: not a button, just a fact about the box. It names the profile whose directory the box uses, or the host, or the plain path when the home belongs to no profile.

The home is read from the container's own metadata (<runtime> inspect <box> --format '{{range .Config.Env}}…HOME=…'), so nothing has to be started to find out, and it uses the runtime helper the app already has, so docker works the same way. It is read once, with the rest of the box's data.

The mapping is a pure function taking the host home and the profile list as arguments, so it is unit-tested rather than reasoned about: host home gives the host label, a profile's directory gives its name, anything else gives itself, empty gives the host label.

A profile could only be made somewhere else

The new-box form's Profile row gains New profile…, between the profiles and Custom folder…. It asks for a name, stores the profile under ~/boxes exactly as the Profiles window does, and selects it - so a profile can be made at the moment it is wanted instead of abandoning the form to open another window.

One GTK detail worth recording, because the first version had the bug: putting the selection back from inside the row's own selected-item-notify handler does not stick - GTK is still applying the change being reacted to. It is deferred to the main loop instead. Without that, cancelling the dialog left the row displaying "New profile…" as if it were a profile. Verified by cancelling and watching the row go back to what it was.

box profile row
new profile inline

Testing

cargo test: 11 pass, 4 of them new on the label mapping.

End to end on a virtual display with an isolated $HOME, an isolated GSettings backend and a stub container runtime reporting a different home per box: the page for a box whose home is a profile's directory shows that profile's name, and one on the shared home shows the host label. Creating a profile from the form writes profiles={'prywatne': '…/boxes/prywatne', 'praca': '…/boxes/praca'} and the row switches to it with its path as the subtitle; cancelling leaves the row where it was.

Creating a box already accepts a custom home directory, but it is a bare
path field: nothing says what it changes, and anyone using it for more than
one box has to remember the paths and retype them.

A profile is that directory with a name on it. The primary menu gains a
Profiles window listing them, each with the directory it points at, a
Browse button that opens it in the file manager, and Remove. Adding one
takes a name and puts the directory under ~/boxes; the directory itself is
created when it is first needed rather than up front, since distrobox makes
it when a box is built and Browse makes it when someone looks.

The new-box form gets a Profile combo listing "Host (shared home)" first,
then the profiles. Picking one fills in the home path; picking Host clears
it, which is distrobox's own default and what every existing box uses. The
folder picker still works for a one-off path, and the value handed to
distrobox is unchanged - so this is a way of choosing the existing option,
not a new mechanism.

Profiles live in GSettings as a name-to-path map, the way exported-app
labels do. Removing one forgets the setting only: the directory and any box
already built on it are left alone.
The first version of this left the Home Directory entry and its folder
button in place beside the new Profile combo, with the combo writing into
the entry. Two controls for one setting, and nothing said which of them
won - the field even kept its "Leave blank for default" label while the
combo was the thing actually deciding.

The row is now the only control. Its choices are Host (shared home), the
profiles, and Custom folder…, which opens the same folder chooser as
before; the chosen directory shows as the row's subtitle, so the path is
still visible. Cancelling the chooser falls back to Host rather than
leaving the row claiming a folder nobody picked.

What is lost is typing a path by hand, which the entry allowed. In a
graphical form a folder chooser is the better way to name a directory, and
the alternative was keeping an ambiguity in the interface to preserve it.
A box gave no sign of which home it was on, so the one thing a profile
decides was invisible once the box existed. Its page now opens with a
Profile row - a fact about the box, not a button - naming the profile whose
directory the box uses, or the host, or the bare path when it belongs to no
profile. The home comes from the container's own metadata, so nothing has
to be started to read it.

The new-box form's Profile row gains a "New profile…" entry, so a profile
can be made at the moment it is wanted rather than in a separate window
first. It asks for a name, stores the profile under ~/boxes, and selects it.

Two things that needed care: putting the selection back from inside the
row's own notify handler does not stick, because GTK is still applying the
change being reacted to - it is deferred to the main loop instead, so a
cancelled dialog never leaves the row sitting on "New profile…". And the
label logic is a pure function taking the host home and the profile list,
so it can be tested without touching GSettings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant