Make Applications a real app manager, and clean up storage without the racket
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -313,4 +313,84 @@ rg --quiet 'image/png' "$call_log" \
|
||||
|
||||
rm -f "$config_home/mimeapps.list"
|
||||
|
||||
# ── One type on its own ──────────────────────────────────────────────────────
|
||||
#
|
||||
# The role rows set a whole family together, which is right almost always and
|
||||
# wrong for the person whose .heic files should open somewhere other than the
|
||||
# rest of their pictures. `set-type` is that escape hatch, and it is the one
|
||||
# verb here that writes a type nobody curated -- so what it accepts is the
|
||||
# question.
|
||||
#
|
||||
# Two guards, and they do different jobs: the type has to be one this system
|
||||
# knows (a typo becomes a handler entry for a MIME type that will never exist),
|
||||
# and the application has to be one that is installed (the same rule the role
|
||||
# rows already keep).
|
||||
|
||||
assert_service_contains 'function searchTypes(query: string): void'
|
||||
assert_service_contains 'function setType(mime: string, desktopId: string): void'
|
||||
|
||||
# The type database, as this fake machine has it.
|
||||
mkdir -p "$data_home/mime"
|
||||
cat >"$data_home/mime/globs2" <<'GLOBS'
|
||||
# weight:type:glob
|
||||
50:image/png:*.png
|
||||
50:image/jpeg:*.jpg
|
||||
50:image/heic:*.heic
|
||||
50:text/markdown:*.md
|
||||
50:application/pdf:*.pdf
|
||||
GLOBS
|
||||
|
||||
# Two applications that declare what they open, so "candidates" has something
|
||||
# true to report rather than passing on an empty list.
|
||||
printf 'MimeType=image/png;image/jpeg;image/heic;\n' >>"$data_home/applications/org.gnome.Loupe.desktop"
|
||||
printf 'MimeType=text/markdown;text/plain;\n' >>"$data_home/applications/panama-nvim.desktop"
|
||||
|
||||
: >"$call_log"
|
||||
search="$($helper search-types heic)" || fail 'search-types failed'
|
||||
jq -e '(.types | type == "array") and has("truncated")' <<<"$search" >/dev/null \
|
||||
|| fail "search-types does not report a list of types and whether it was cut short: $search"
|
||||
jq -e '[.types[] | has("mime") and has("handler") and has("candidates")] | all' <<<"$search" >/dev/null \
|
||||
|| fail "a search result is missing its type, its current handler, or the applications that could open it: $search"
|
||||
jq -e '[.types[].mime] | index("image/heic") != null' <<<"$search" >/dev/null \
|
||||
|| fail "searching an extension did not find the type it belongs to: $search"
|
||||
jq -e '[.types[] | select(.mime == "image/heic") | .candidates[].id]
|
||||
| index("org.gnome.Loupe.desktop") != null' <<<"$search" >/dev/null \
|
||||
|| fail "an application that declares the type is not offered for it: $search"
|
||||
|
||||
# Candidates are installed applications, never a name read out of a registry.
|
||||
discovered="$(cd "$data_home/applications" && ls)"
|
||||
while read -r candidate; do
|
||||
[[ -n "$candidate" ]] || continue
|
||||
rg -Fxq "$candidate" <<<"$discovered" \
|
||||
|| fail "search-types offers '$candidate', which is not installed on this machine"
|
||||
done < <(jq -r '[.types[].candidates[].id] | unique[]' <<<"$search")
|
||||
|
||||
# A one-character query is not a search: it would return the whole database.
|
||||
jq -e '(.types | length) == 0' <<<"$($helper search-types a)" >/dev/null \
|
||||
|| fail 'a single character was treated as a search of the whole type database'
|
||||
|
||||
: >"$call_log"
|
||||
$helper set-type image/heic org.gnome.Loupe.desktop
|
||||
assert_call $'default\norg.gnome.Loupe.desktop\nimage/heic'
|
||||
|
||||
# One type, and only that type: the whole point of the escape hatch is that it
|
||||
# leaves the rest of the family where it was.
|
||||
[[ "$(rg --count '^default$' "$call_log")" == "1" ]] \
|
||||
|| fail 'setting one file type wrote more than one'
|
||||
|
||||
: >"$call_log"
|
||||
if $helper set-type image/heic org.example.Missing.desktop >/dev/null 2>&1; then
|
||||
fail 'set-type accepted an application that is not installed'
|
||||
fi
|
||||
if $helper set-type image/heic ../escape.desktop >/dev/null 2>&1; then
|
||||
fail 'set-type accepted an unsafe desktop id'
|
||||
fi
|
||||
for bad_type in 'image' 'image/' '/png' 'image/png;rm -rf /' '' '../../etc/passwd' \
|
||||
'image/does-not-exist'; do
|
||||
if $helper set-type "$bad_type" org.gnome.Loupe.desktop >/dev/null 2>&1; then
|
||||
fail "set-type accepted a type this system does not have: ${bad_type@Q}"
|
||||
fi
|
||||
done
|
||||
[[ ! -s "$call_log" ]] || fail "a refused set-type still reached xdg-mime: $(cat "$call_log")"
|
||||
|
||||
printf 'default apps contract: PASS\n'
|
||||
|
||||
Reference in New Issue
Block a user