Splits setup.sh into lib/common.sh, lib/session.sh and seven modules (3 DE, 4 TWM). Targets a bare Fedora 44+ install. Fixes carried over from the first build: - DEBUG_MODE was unbound under set -u, aborting the script at the version banner - mangled 'echohttps://...' line left over from the starburst split - set -e was missing entirely; --debug flag parsing restored - unguarded 'clear' aborted the run without TERM - $PRETTY_NAME unguarded under set -u - modules were sourced, leaking shell options into the parent - Flathub added twice (system-wide + per-user) - no dnf5-plugins check before using 'dnf config-manager' - no Fedora release gate - /usr/share/xsessions assumed to exist when writing session entries
136 lines
5.2 KiB
Markdown
136 lines
5.2 KiB
Markdown
# Fedora Unified Config
|
||
|
||
Unified configuration for **bare/minimal Fedora 44 and newer**. Pick a desktop
|
||
environment and optionally a tiling window manager; the script wires up repos,
|
||
packages, the greeter and the session entry.
|
||
|
||
This repo is the Fedora-only successor to `starburst`. Everything multi-distro
|
||
(Arch, Debian, Ubuntu branches, OS guessing, per-distro package helpers) is gone
|
||
on purpose.
|
||
|
||
## Usage
|
||
|
||
```bash
|
||
git clone https://git.ku-it.org/yuri/fedora.git
|
||
cd fedora
|
||
./setup.sh # interactive: choose DE, then TWM
|
||
./setup.sh --debug # same, but pause after each section
|
||
```
|
||
|
||
Non-interactive:
|
||
|
||
```bash
|
||
./setup.sh --yes --de=none --twm=niri
|
||
./setup.sh --yes --de=gnome --twm=none
|
||
```
|
||
|
||
Run as your **normal user**, not root. `sudo` is used where needed.
|
||
|
||
## Layout
|
||
|
||
```
|
||
setup.sh entrypoint: args, preconditions, base setup, menus, dispatch
|
||
lib/common.sh colours, logging, dnf helpers, rpmfusion/terra, nerd fonts
|
||
lib/session.sh display-manager detection/switching, session entries
|
||
modules/de/{gnome,plasma,xfce}.sh
|
||
modules/twm/{niri,hyprland,mango,chadwm}.sh
|
||
```
|
||
|
||
Modules are **separate processes**, not sourced into `setup.sh`. That means a
|
||
module's own `set -e` cannot leak into the caller, and every module can be run
|
||
on its own for testing:
|
||
|
||
```bash
|
||
DE=none TWM=niri DEBUG_MODE=false bash modules/twm/niri.sh
|
||
```
|
||
|
||
Each module pulls in `lib/` by relative path, so it works both ways.
|
||
|
||
## Selection matrix
|
||
|
||
| DE | TWM | Result |
|
||
|---|---|---|
|
||
| any | any | DE provides the session; TWM is added alongside it |
|
||
| `none` | any | TWM-only machine, SDDM installed as the greeter |
|
||
| any | `none` | plain desktop, no tiling WM |
|
||
| `none` | `none` | **refused** — that is not a graphical system |
|
||
|
||
### Desktop environments
|
||
|
||
| DE | dnf group (tried in order) | native greeter |
|
||
|---|---|---|
|
||
| `gnome` | `gnome-desktop`, `gnome-desktop-environment`, `workstation-product-environment` | gdm |
|
||
| `plasma` | `kde-desktop`, `kde-desktop-environment` | sddm |
|
||
| `xfce` | `xfce-desktop`, `xfce-desktop-environment` | lightdm |
|
||
|
||
### Tiling window managers
|
||
|
||
| TWM | Source | Session type | Notes |
|
||
|---|---|---|---|
|
||
| `niri` | Fedora repos + Terra (for `noctalia`) | Wayland | Ships its own session entry |
|
||
| `hyprland` | Fedora repos | Wayland | Ships its own session entry |
|
||
| `mango` | **Terra repo only** | Wayland | Session entry written if the package lacks one |
|
||
| `chadwm` | **built from source** | **X11** | dwm fork; not packaged anywhere for Fedora |
|
||
|
||
`chadwm` is the only X11 entry in the menu. The other three are Wayland
|
||
compositors — do not expect the same config story from it.
|
||
|
||
## Display manager policy
|
||
|
||
* A **DE module** leaves the DE's own greeter alone (GNOME→gdm, Plasma→sddm,
|
||
XFCE→lightdm). It never fights a desktop over its own login screen.
|
||
* A **TWM module** enforces **SDDM**, because it is the only greeter that lists
|
||
Wayland compositors *and* X11 sessions in one menu.
|
||
* Either way `graphical.target` becomes the default.
|
||
|
||
## Design rules
|
||
|
||
1. **Fail loudly, early.** `set -e` is on unless `--debug`. Unsupported distro,
|
||
release below 44, `DE=none` + `TWM=none`, and a missing module all abort with
|
||
an explanation instead of half-installing.
|
||
2. **Be idempotent.** Re-running must be safe. Repos are checked with `rpm -q`
|
||
before being added, the Nerd Font is skipped if already present, and session
|
||
entries are not overwritten.
|
||
3. **Prefer official repos, then Terra, then a source build.** That order is why
|
||
only `mango` and `chadwm` need special handling.
|
||
4. **No silent optional failures.** `install_optional` warns and continues for
|
||
nice-to-haves; everything load-bearing uses `install_packages` and aborts.
|
||
5. **Guard anything environment-dependent.** `clear` needs `|| true` (no `TERM`
|
||
under cron/pipes), `os-release` fields are defaulted, and
|
||
`/usr/share/xsessions` is created before writing into it.
|
||
|
||
## Testing
|
||
|
||
The script was verified on a non-Fedora host with a stateful stub harness
|
||
(fake `sudo`/`dnf`/`rpm`/`systemctl`/`git`/`make`/`curl`, a fake `os-release`,
|
||
and sandboxed `/usr` + `$HOME`). Covered: every DE×(TWM|none) combination, the
|
||
refusal paths, `--help`/bad args, interactive menus, `--debug` abort, and
|
||
re-running for idempotency.
|
||
|
||
`OS_RELEASE_FILE` is overridable purely so the preconditions can be tested:
|
||
|
||
```bash
|
||
OS_RELEASE_FILE=/tmp/fake-os-release ./setup.sh --yes --de=xfce --twm=chadwm
|
||
```
|
||
|
||
## Known limitations
|
||
|
||
* `noctalia` and `mangowc` come from **Terra**, a third-party repo. The
|
||
package layout there is not guaranteed across Fedora releases; `mango` aborts
|
||
with build-from-source instructions if the package is missing.
|
||
* Package *names* are not verified by installation in this repo's test harness —
|
||
only control flow is. First real run on a fresh F44 box is the actual proof.
|
||
* `gnome-tweaks`/`gnome-extensions-app`, `wofi`, `waybar`, `hyprlock` and friends
|
||
are installed with `install_optional`, so a rename will warn rather than fail.
|
||
|
||
## Roadmap
|
||
|
||
- [ ] Profile files (`--profile=laptop`) instead of individual flags
|
||
- [ ] Optional dotfiles layer (noctalia/hyprland/niri configs)
|
||
- [ ] `--dry-run` that prints the dnf transaction without applying it
|
||
- [ ] Pre-flight report: what is already installed, what would change
|
||
|
||
## License
|
||
|
||
See `LICENSE`.
|