It claimed 121 contracts when there were 125, one day after the number was written, and it documented every panama subcommand except the one added last -- so `panama apps` existed and the README did not mention it. A number in prose is worth something as a claim somebody relies on and nothing once it is wrong, so it is either checked or it should not be there. This checks it, counted the way the runner collects the suite rather than by a second idea of what a contract is, and checks that every subcommand the README documents is one the dispatcher actually handles -- a listed command that errors reads as a broken install rather than a stale document. Claude-Session: https://claude.ai/code/session_01Q84axqUE5inJhf5Jz9CFy1
159 lines
7.7 KiB
Markdown
159 lines
7.7 KiB
Markdown
# Panama
|
|
|
|
Formerly Sunhat. A personal config for Fedora, with the intention of helping a
|
|
user set up their Fedora system with one command.
|
|
|
|
```sh
|
|
git clone https://git.gbrown.org/gib/Panama.git ~/.local/share/Panama
|
|
~/.local/share/Panama/install
|
|
```
|
|
|
|
`install` asks its questions first and then runs the stages in `setup/scripts/`
|
|
in order, without stopping again:
|
|
|
|
| Script | Does |
|
|
|---|---|
|
|
| `interview` | Every prompt, before anything is installed. Answers last one run and are never written to a durable path |
|
|
| `install-packages` | Repos (RPM Fusion, Terra, Hyprland COPR), the package lists in `setup/packages/`, then whichever optional categories were chosen |
|
|
| `link-dotfiles` | Symlinks `config/dot/<name>` → `~/.config/<name>`, and seeds the wallpaper, cursor theme and Firefox chrome |
|
|
| `change-settings` | Copies `config/copy/` over `/`, applies gsettings, enables user services |
|
|
| `link-vicinae-scripts` | Publishes the Vicinae script commands |
|
|
| `setup-identity` | git config, `gh auth login`, an SSH key — whichever were asked for |
|
|
| `install-hardware` | NVIDIA, Secure Boot enrollment, Fedora's extras, firmware — each only if it was asked for. Last, because enrollment and firmware are consumed at the next boot |
|
|
|
|
The run ends with a health summary from `panama-doctor`, which reports what is
|
|
actually running rather than what was attempted. It never fails the install: on a
|
|
fresh machine it legitimately reports things as not yet configured.
|
|
|
|
### Optional applications
|
|
|
|
Every machine gets the lists in `setup/packages/`. The interview also offers the
|
|
categories in `setup/packages/extras/` as a checklist, so a work laptop need not
|
|
acquire emulators and a desktop need not skip Steam. Nothing is preselected.
|
|
|
|
A category is one file. A bare line is a dnf package and a `flatpak:` line is a
|
|
Flathub ID, because the applications in a category do not all come from one
|
|
place. Adding a category is adding a file — the menu is read from the directory,
|
|
not written down anywhere.
|
|
|
|
Existing configs are moved to `config/old/` rather than overwritten.
|
|
|
|
## The desktop
|
|
|
|
Hyprland, with a shell written from scratch. It began as a replacement for a
|
|
GNOME session — Forge for tiling, Dash-to-Dock, Openbar, Vitals — and was built
|
|
to reproduce it closely enough that muscle memory transferred: same keybinds,
|
|
same panel contents, same dock, same Tokyo Night Moon palette.
|
|
|
|
That is history now rather than a second option. Panama installs and configures
|
|
one desktop, and the GNOME session it grew out of is neither installed nor
|
|
configured here. What each piece replaced is recorded in
|
|
[`config/dot/hypr/DESKTOP-PARITY.md`](config/dot/hypr/DESKTOP-PARITY.md) and in
|
|
the comments of the components themselves, because knowing what a thing was
|
|
modelled on explains why it behaves the way it does.
|
|
|
|
GNOME is not gone from the machine: `gnome-control-center` is a declared
|
|
dependency, and Panama's own Settings hands off to it for the panels it
|
|
deliberately does not own — Online Accounts, Color, Sound, Network, Keyboard,
|
|
Privacy, Wellbeing, Accessibility, and System for users, date and time, region
|
|
and remote desktop. The allow-list in
|
|
[`services/SystemSettings.qml`](config/dot/quickshell/services/SystemSettings.qml)
|
|
is what decides; anything not on it is a panel Panama owns itself.
|
|
|
|
| Piece | What it is |
|
|
|---|---|
|
|
| `config/dot/hypr/` | Compositor config. **Lua, not hyprlang** — see its README |
|
|
| `config/dot/quickshell/` | The shell: bar, dock, Continuum overview, Settings, Screen Intelligence, focus sessions, quick settings, notifications, screenshot UI |
|
|
| `config/dot/vicinae/` | Raycast-style launcher, themed |
|
|
| `config/dot/uwsm/` | Session environment (see the uwsm caveat in the hypr README) |
|
|
| `config/dot/wofi/` | Fallback launcher, in case the shell fails to start |
|
|
| `config/dot/xdg-desktop-portal/` | Portal backend routing |
|
|
|
|
**Start here: [`config/dot/hypr/README.md`](config/dot/hypr/README.md)** — it
|
|
covers the Lua migration, the uwsm environment gotcha, the HDR decision, the
|
|
full keymap, and troubleshooting.
|
|
|
|
Log in as **"Hyprland (uwsm-managed)"**, not plain "Hyprland".
|
|
|
|
## Layout
|
|
|
|
```
|
|
bin/ Small user-facing commands on PATH; `panama` is the entry point
|
|
config/
|
|
bash/ .bashrc, aliases, env (env is gitignored)
|
|
copy/ Files copied verbatim over / (needs sudo)
|
|
dot/ Symlinked into ~/.config
|
|
firefox/ Vendored Firefox chrome, linked into the browser profile
|
|
local/ Icons and the cursor theme, linked into ~/.local/share
|
|
old/ Backups of whatever was replaced (gitignored)
|
|
wallpapers/ Copied into ~/Pictures/Wallpapers when absent
|
|
setup/
|
|
apps/ Applications built from source, one file each
|
|
packages/ One package per line; extras/ holds the optional categories
|
|
scripts/ Run in order by ./install
|
|
tests/ Contracts. See below
|
|
docs/ Settings reference, and the design specs behind the work
|
|
```
|
|
|
|
## Tests
|
|
|
|
126 of them, under `tests/`. Run the lot, or a subset by pattern:
|
|
|
|
```sh
|
|
panama test # everything
|
|
panama test dock # just the ones matching "dock"
|
|
tests/setup/interview-contract # or one directly; they are plain executables
|
|
```
|
|
|
|
They are called contracts rather than unit tests because that is what they are:
|
|
each one pins a decision that was expensive to get right and is cheap to undo by
|
|
accident. Most read or measure the real thing — launching a shell to measure a
|
|
surface's geometry, standing stub commands on `PATH` to see what a stage would
|
|
have installed, running a script against a throwaway `HOME` — rather than
|
|
asserting things about source text, because the bugs worth catching here have all
|
|
been ones that source text looked fine for.
|
|
|
|
```
|
|
tests/setup/ The installer: the interview, package lists, hardware, extras
|
|
tests/quickshell/ The shell and its settings pages
|
|
tests/hypr/ The compositor config
|
|
```
|
|
|
|
## The `panama` command
|
|
|
|
```sh
|
|
panama update # review, commit and sync this repo
|
|
panama edit # open it in Neovim
|
|
panama doctor # what is actually running, not what was installed
|
|
panama test # every contract, or a subset by pattern
|
|
panama upgrade # re-run ./install from anywhere
|
|
panama apps # choose applications to install, by category
|
|
panama app # applications no repository carries; build one by name
|
|
```
|
|
|
|
`panama apps` is the optional-application catalog, opened after the fact. The
|
|
interview offers the same categories during `./install`, whole; this picks a
|
|
category and then the applications inside it, so a machine can acquire Slack in
|
|
March without having wanted Discord in January. Both read
|
|
`setup/lib/extras-catalog`, so the two cannot describe different catalogues.
|
|
|
|
A category is one file under `setup/packages/extras/`. A bare line is a dnf
|
|
package, a `flatpak:` line is a Flathub id, `| Name` gives the menu something
|
|
readable, and an indented line belongs to the entry above it — which is how OBS
|
|
carries its sixteen plugin extensions as one thing to tick.
|
|
|
|
`panama app` is deliberately not part of `./install`. Everything else Panama
|
|
installs comes from dnf or Flathub; these are built from source because no
|
|
packaged form exists, and a source build is slow, wants the network throughout,
|
|
and depends on an upstream that moves. That is the failure the interview exists
|
|
to prevent, so asking for one is something you do on purpose — and it is also
|
|
how you rebuild when a new version ships. Nothing is pinned: each build takes
|
|
the current upstream and reports a failure rather than working around it.
|
|
|
|
Adding one is adding a file to `setup/apps/`, and the file has to say why the
|
|
exception exists.
|
|
|
|
None of the scripts in this repository carry a `.sh` extension. A shebang and
|
|
the executable bit already select the interpreter, and the extension only
|
|
becomes something to keep in sync — which it did not stay.
|