fix(mime): text/plain falls through to Text Editor on live (#119)
All checks were successful
Check / eval (push) Successful in 4m5s
All checks were successful
Check / eval (push) Successful in 4m5s
A singleton default naming code.desktop left the live ISO with no text handler — GIO skips missing .desktop files and offers nothing. Prefer vscode when present, then org.gnome.TextEditor.desktop. Live also gains mpv (video defaults had the same hole; free via the template pin). checks.live-baseline-apps now requires every Default Applications key to resolve to a present .desktop on live (HM + system path) and on the default template install. Proved to fail on a vscode-only text/plain. Verified: V2 (live-baseline-apps green + prove-to-fail); V0 flake check.
This commit is contained in:
94
flake.nix
94
flake.nix
@@ -560,23 +560,37 @@
|
||||
touch $out
|
||||
'';
|
||||
|
||||
# Live-ISO baseline apps (ROADMAP § live-ISO baseline apps, #103).
|
||||
# The live session shipped no
|
||||
# browser and no office for as long as it existed — the thing a user
|
||||
# judges the distro by before installing, and boots to rescue a dead
|
||||
# machine. Nothing in a build fails when an app silently leaves the
|
||||
# live profile (it just stops being in the launcher, which is
|
||||
# invisible until someone boots the ISO on real hardware and looks),
|
||||
# so assert both halves: on PATH *and* a .desktop the launcher can
|
||||
# see. Same artifacts the ISO ships, no ISO build.
|
||||
# Live-ISO baseline apps (ROADMAP § live-ISO baseline apps, #103)
|
||||
# plus the mime-default presence guard (#94 / #119). The live
|
||||
# session shipped no browser and no office for as long as it
|
||||
# existed — the thing a user judges the distro by before installing,
|
||||
# and boots to rescue a dead machine. Nothing in a build fails when
|
||||
# an app silently leaves the live profile (it just stops being in
|
||||
# the launcher), and a mime default that names a missing .desktop is
|
||||
# silently skipped by GIO (no handler at all) — so assert both:
|
||||
# binaries + launcher entries for the baseline suite, and that
|
||||
# every Default Applications key has at least one listed .desktop
|
||||
# present in the live profile or system path (thunar is system-side).
|
||||
# Same artifacts the ISO ships, no ISO build.
|
||||
live-baseline-apps =
|
||||
let
|
||||
liveHm =
|
||||
self.nixosConfigurations.nomarchy-live.config.home-manager.users.${username};
|
||||
gen = liveHm.home.activationPackage;
|
||||
# system.path carries NixOS-side apps (thunar); HM-only
|
||||
# home-path does not. A mime default that only names a
|
||||
# system desktop must still resolve.
|
||||
sysPath =
|
||||
self.nixosConfigurations.nomarchy-live.config.system.path;
|
||||
# Template install path: same mime defaults, different package
|
||||
# set (vscode present, gnome-text-editor not). Guard both so
|
||||
# a live-only fix cannot re-break the installed machine.
|
||||
templateGen = downstream.homeConfigurations.me.activationPackage;
|
||||
templateSys =
|
||||
downstream.nixosConfigurations.default.config.system.path;
|
||||
in
|
||||
pkgs.runCommand "nomarchy-live-baseline-apps"
|
||||
{ nativeBuildInputs = [ pkgs.gnugrep pkgs.findutils ]; }
|
||||
{ nativeBuildInputs = [ pkgs.gnugrep pkgs.findutils pkgs.python3 ]; }
|
||||
''
|
||||
set -euo pipefail
|
||||
apps=${gen}/home-path/share/applications
|
||||
@@ -590,11 +604,12 @@
|
||||
impress.desktop \
|
||||
org.gnome.TextEditor.desktop \
|
||||
io.bassi.Amberol.desktop \
|
||||
mpv.desktop \
|
||||
org.gnome.Snapshot.desktop; do
|
||||
test -f "$apps/$d" || { echo "live-baseline-apps: MISSING launcher entry $d"; exit 1; }
|
||||
done
|
||||
|
||||
for b in chromium libreoffice gnome-text-editor amberol snapshot; do
|
||||
for b in chromium libreoffice gnome-text-editor amberol mpv snapshot; do
|
||||
test -x "$bins/$b" || { echo "live-baseline-apps: MISSING binary $b"; exit 1; }
|
||||
done
|
||||
|
||||
@@ -603,16 +618,67 @@
|
||||
# so GIO silently skipped the entry and the live session had
|
||||
# no default browser at all).
|
||||
mimes=${gen}/home-files/.config/mimeapps.list
|
||||
grep -q '^x-scheme-handler/https=chromium-browser.desktop' "$mimes"
|
||||
grep -q '^x-scheme-handler/https=chromium-browser.desktop' "$mimes" \
|
||||
|| { echo "live-baseline-apps: https mime must name chromium-browser.desktop (#94)"; exit 1; }
|
||||
test -f "$apps/chromium-browser.desktop"
|
||||
|
||||
# text/plain must prefer vscode but fall through to the live
|
||||
# editor (#119) — never a singleton that only names code.
|
||||
grep -qE '^text/plain=.*org\.gnome\.TextEditor\.desktop' "$mimes" \
|
||||
|| { echo "live-baseline-apps: text/plain must fall through to org.gnome.TextEditor.desktop (#119)"; exit 1; }
|
||||
test -f "$apps/org.gnome.TextEditor.desktop"
|
||||
|
||||
# Every Default Applications key: at least one listed
|
||||
# .desktop must exist in home-path OR system path. A key
|
||||
# whose every entry is missing is the #94/#119 bug class.
|
||||
# Covers live *and* the default template install.
|
||||
python3 - "$mimes" "$apps" "${sysPath}/share/applications" \
|
||||
"${templateGen}/home-files/.config/mimeapps.list" \
|
||||
"${templateGen}/home-path/share/applications" \
|
||||
"${templateSys}/share/applications" <<'PY'
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def check(label, mimes, *app_dirs):
|
||||
text = Path(mimes).read_text()
|
||||
in_defaults = False
|
||||
bad = []
|
||||
for line in text.splitlines():
|
||||
if line.startswith("["):
|
||||
in_defaults = line.strip() == "[Default Applications]"
|
||||
continue
|
||||
if not in_defaults or not line.strip() or line.startswith("#"):
|
||||
continue
|
||||
if "=" not in line:
|
||||
continue
|
||||
key, val = line.split("=", 1)
|
||||
desktops = [d for d in val.split(";") if d.strip()]
|
||||
if not desktops:
|
||||
bad.append(f"{key}= (empty)")
|
||||
continue
|
||||
if not any(
|
||||
any((Path(d) / desk).is_file() for d in app_dirs)
|
||||
for desk in desktops
|
||||
):
|
||||
bad.append(f"{key}={';'.join(desktops)} (none present)")
|
||||
if bad:
|
||||
print(f"live-baseline-apps: mime defaults missing on {label}:")
|
||||
for b in bad:
|
||||
print(f" {b}")
|
||||
sys.exit(1)
|
||||
print(f"live-baseline-apps: mime defaults ok on {label}")
|
||||
|
||||
check("live", sys.argv[1], sys.argv[2], sys.argv[3])
|
||||
check("template", sys.argv[4], sys.argv[5], sys.argv[6])
|
||||
PY
|
||||
|
||||
# Firefox is deliberately absent — a second browser is the one
|
||||
# item in #103's list that costs a real closure, and chromium
|
||||
# owns the mime default (Bernardo 2026-07-14). If it ever
|
||||
# ships here, that is a size decision, not a drive-by.
|
||||
test ! -f "$apps/firefox.desktop" || { echo "live-baseline-apps: firefox reappeared — size decision, see #103"; exit 1; }
|
||||
|
||||
echo "live-baseline-apps: ok — browser, office, editor, music, camera on PATH + in the launcher"
|
||||
echo "live-baseline-apps: ok — browser, office, editor, music, video, camera + mime defaults resolve"
|
||||
touch $out
|
||||
'';
|
||||
|
||||
@@ -1919,6 +1985,8 @@
|
||||
libreoffice-fresh # documents/sheets/slides off a dying disk
|
||||
gnome-text-editor # the maintained gedit successor
|
||||
amberol # music player (also in the template)
|
||||
mpv # video (mime defaults → mpv.desktop; also
|
||||
# template — free on the ISO via the pin)
|
||||
snapshot # camera — the maintained Cheese successor
|
||||
];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user