diff --git a/AGENTS.md b/AGENTS.md index ad8a629e..17a4f9ee 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,7 @@ matching guide before starting: - Use bash 5 conditionals: use `[[ ]]` for string/file tests and `(( ))` for numeric tests - In `[[ ]]`, don't quote variables, but do quote string literals when comparing values (e.g., `[[ $branch == "dev" ]]`) - Prefer `(( ))` over numeric operators inside `[[ ]]` (e.g., `(( count < 50 ))`, not `[[ $count -lt 50 ]]`) +- Prefer a full `if`/`else` conditional for simple two-path control flow; don't rely on `exec` or `exit` in one branch to make following statements unreachable - For strings/paths with spaces, quote them instead of escaping spaces with `\ ` (e.g., `"$APP_DIR/Disk Usage.desktop"`, not `$APP_DIR/Disk\ Usage.desktop`) - Shebangs must use `#!/bin/bash` consistently (never `#!/usr/bin/env bash`) - Scripts under `install/` and `migrations/` may be sourced and intentionally omit shebangs diff --git a/bin/omarchy-default-browser b/bin/omarchy-default-browser index f53ccf9a..3e54bd3b 100755 --- a/bin/omarchy-default-browser +++ b/bin/omarchy-default-browser @@ -4,6 +4,12 @@ # omarchy:args=[chromium|chrome|brave|brave-origin|edge|firefox|zen] # omarchy:examples=omarchy default browser firefox | omarchy default browser brave +installing=false +if [[ ${1:-} == "--install" ]]; then + installing=true + shift +fi + if (($# == 0)); then case "$(env -u BROWSER xdg-settings get default-web-browser)" in chromium.desktop) echo "chromium" ;; @@ -19,19 +25,27 @@ if (($# == 0)); then fi case "$1" in -chromium) desktop_id="chromium.desktop"; name="Chromium"; glyph= ;; -chrome) desktop_id="google-chrome.desktop"; name="Chrome"; glyph=󰊯 ;; -brave) desktop_id="brave-browser.desktop"; name="Brave"; glyph=󰖟 ;; -brave-origin) desktop_id="brave-origin.desktop"; name="Brave Origin"; glyph=󰖟 ;; -edge) desktop_id="microsoft-edge.desktop"; name="Edge"; glyph=󰇩 ;; -firefox) desktop_id="firefox.desktop"; name="Firefox"; glyph=󰈹 ;; -zen) desktop_id="zen.desktop"; name="Zen"; glyph=󰖟 ;; +chromium) browser="chromium"; command="chromium"; desktop_id="chromium.desktop"; name="Chromium"; glyph= ;; +chrome) browser="chrome"; command="google-chrome-stable"; desktop_id="google-chrome.desktop"; name="Chrome"; glyph=󰊯 ;; +brave) browser="brave"; command="brave"; desktop_id="brave-browser.desktop"; name="Brave"; glyph=󰖟 ;; +brave-origin) browser="brave-origin"; command="brave-origin"; desktop_id="brave-origin.desktop"; name="Brave Origin"; glyph=󰖟 ;; +edge) browser="edge"; command="microsoft-edge-stable"; desktop_id="microsoft-edge.desktop"; name="Edge"; glyph=󰇩 ;; +firefox) browser="firefox"; command="firefox"; desktop_id="firefox.desktop"; name="Firefox"; glyph=󰈹 ;; +zen) browser="zen"; command="zen-browser"; desktop_id="zen.desktop"; name="Zen"; glyph=󰖟 ;; *) echo "Usage: omarchy-default-browser " exit 1 ;; esac +if omarchy-cmd-missing "$command"; then + if [[ $installing == "false" ]]; then + exec omarchy-launch-floating-terminal-with-presentation omarchy-default-browser --install "$browser" + else + omarchy-install-browser "$browser" || exit 1 + fi +fi + env -u BROWSER xdg-settings set default-web-browser "$desktop_id" || exit 1 omarchy-notification-send -g $glyph "$name is now the default browser" diff --git a/bin/omarchy-default-editor b/bin/omarchy-default-editor index bf14dc44..25134081 100755 --- a/bin/omarchy-default-editor +++ b/bin/omarchy-default-editor @@ -4,6 +4,12 @@ # omarchy:args=[code|cursor|zed|sublime_text|helix|vim|emacs|nvim] # omarchy:examples=omarchy default editor | omarchy default editor code | omarchy default editor helix +installing=false +if [[ ${1:-} == "--install" ]]; then + installing=true + shift +fi + editor_file="$HOME/.local/state/omarchy/defaults/editor" if (($# == 0)); then @@ -16,20 +22,37 @@ if (($# == 0)); then fi case "$1" in -code) editor="code"; name="VSCode"; glyph= ;; -cursor) editor="cursor"; name="Cursor"; glyph= ;; -zed | zeditor) editor="zeditor"; name="Zed"; glyph= ;; -sublime_text) editor="sublime_text"; name="Sublime Text"; glyph= ;; -helix) editor="helix"; name="Helix"; glyph= ;; -vim) editor="vim"; name="Vim"; glyph= ;; -emacs) editor="emacs"; name="Emacs"; glyph= ;; -nvim) editor="nvim"; name="Neovim"; glyph= ;; +code) selection="code"; editor="code"; name="VSCode"; glyph= ;; +cursor) selection="cursor"; editor="cursor"; name="Cursor"; glyph= ;; +zed | zeditor) selection="zed"; editor="zeditor"; name="Zed"; glyph= ;; +sublime_text) selection="sublime_text"; editor="sublime_text"; name="Sublime Text"; glyph= ;; +helix) selection="helix"; editor="helix"; name="Helix"; glyph= ;; +vim) selection="vim"; editor="vim"; name="Vim"; glyph= ;; +emacs) selection="emacs"; editor="emacs"; name="Emacs"; glyph= ;; +nvim) selection="nvim"; editor="nvim"; name="Neovim"; glyph= ;; *) echo "Usage: omarchy-default-editor " exit 1 ;; esac +if omarchy-cmd-missing "$editor"; then + if [[ $installing == "false" ]]; then + exec omarchy-launch-floating-terminal-with-presentation omarchy-default-editor --install "$selection" + else + case "$selection" in + code) omarchy-install-editor-vscode ;; + cursor) omarchy-pkg-add cursor-bin ;; + zed) omarchy-install-editor-zed ;; + sublime_text) omarchy-pkg-add sublime-text-4 ;; + helix) omarchy-install-editor-helix ;; + vim) omarchy-pkg-add vim ;; + emacs) omarchy-install-editor-emacs ;; + nvim) omarchy-pkg-add neovim ;; + esac || exit 1 + fi +fi + mkdir -p "$(dirname "$editor_file")" printf '%s\n' "$editor" >"$editor_file" diff --git a/bin/omarchy-default-terminal b/bin/omarchy-default-terminal index ca0ee1d3..ff0e5df2 100755 --- a/bin/omarchy-default-terminal +++ b/bin/omarchy-default-terminal @@ -4,6 +4,12 @@ # omarchy:args=[alacritty|foot|ghostty|kitty] # omarchy:examples=omarchy default terminal ghostty | omarchy default terminal kitty +installing=false +if [[ ${1:-} == "--install" ]]; then + installing=true + shift +fi + if (($# == 0)); then desktop_id=$(xdg-terminal-exec --print-id 2>/dev/null || true) desktop_id=${desktop_id%%:*} @@ -18,16 +24,24 @@ if (($# == 0)); then fi case "$1" in -alacritty) desktop_id="Alacritty.desktop"; name="Alacritty"; glyph= ;; -foot) desktop_id="foot.desktop"; name="Foot"; glyph= ;; -ghostty) desktop_id="com.mitchellh.ghostty.desktop"; name="Ghostty"; glyph= ;; -kitty) desktop_id="kitty.desktop"; name="Kitty"; glyph= ;; +alacritty) terminal="alacritty"; desktop_id="Alacritty.desktop"; name="Alacritty"; glyph= ;; +foot) terminal="foot"; desktop_id="foot.desktop"; name="Foot"; glyph= ;; +ghostty) terminal="ghostty"; desktop_id="com.mitchellh.ghostty.desktop"; name="Ghostty"; glyph= ;; +kitty) terminal="kitty"; desktop_id="kitty.desktop"; name="Kitty"; glyph= ;; *) echo "Usage: omarchy-default-terminal " exit 1 ;; esac +if omarchy-cmd-missing "$terminal"; then + if [[ $installing == "false" ]]; then + exec omarchy-launch-floating-terminal-with-presentation omarchy-default-terminal --install "$terminal" + else + omarchy-install-terminal "$terminal" || exit 1 + fi +fi + cat >~/.config/xdg-terminals.list < -# omarchy:examples=omarchy install browser firefox | omarchy install browser brave +# omarchy:args= +# omarchy:examples=omarchy install browser chromium | omarchy install browser firefox + +set -e setup_policy_directory() { sudo mkdir -p "$1" @@ -34,6 +36,15 @@ setup_firefox_wayland() { } case $1 in +chromium) + echo "Installing Chromium..." + omarchy-pkg-add chromium + + setup_policy_directory /etc/chromium/policies/managed + copy_chromium_flags ~/.config/chromium-flags.conf + omarchy-theme-set-browser + announce_browser_installed "Chromium" + ;; chrome) echo "Installing Chrome..." omarchy-pkg-aur-add google-chrome || exit 1 @@ -87,7 +98,7 @@ zen) announce_browser_installed "Zen" ;; *) - echo "Usage: omarchy-install-browser " + echo "Usage: omarchy-install-browser " exit 1 ;; esac diff --git a/default/omarchy/omarchy-menu.jsonc b/default/omarchy/omarchy-menu.jsonc index 859f089b..372a7025 100644 --- a/default/omarchy/omarchy-menu.jsonc +++ b/default/omarchy/omarchy-menu.jsonc @@ -140,27 +140,27 @@ "setup.default.agent.opencode": {"icon":"","iconFont":"omarchy","label":"OpenCode","checked":"[[ \"$(omarchy-default-agent)\" == \"opencode\" ]]","action":"omarchy-default-agent opencode"}, "setup.default.agent.pi": {"icon":"","iconFont":"omarchy","label":"Pi","checked":"[[ \"$(omarchy-default-agent)\" == \"pi\" ]]","action":"omarchy-default-agent pi"}, "setup.default.browser": {"icon":"","label":"Browser","title":"Default Browser"}, - "setup.default.browser.chromium": {"icon":"","label":"Chromium","when":"omarchy-cmd-present chromium","checked":"[[ \"$(omarchy-default-browser)\" == \"chromium\" ]]","action":"omarchy-default-browser chromium"}, - "setup.default.browser.chrome": {"icon":"󰊯","label":"Chrome","when":"omarchy-cmd-present google-chrome-stable","checked":"[[ \"$(omarchy-default-browser)\" == \"chrome\" ]]","action":"omarchy-default-browser chrome"}, - "setup.default.browser.brave": {"icon":"󰖟","label":"Brave","when":"omarchy-cmd-present brave","checked":"[[ \"$(omarchy-default-browser)\" == \"brave\" ]]","action":"omarchy-default-browser brave"}, - "setup.default.browser.brave-origin": {"icon":"󰖟","label":"Brave Origin","when":"omarchy-cmd-present brave-origin","checked":"[[ \"$(omarchy-default-browser)\" == \"brave-origin\" ]]","action":"omarchy-default-browser brave-origin"}, - "setup.default.browser.edge": {"icon":"󰇩","label":"Edge","when":"omarchy-cmd-present microsoft-edge-stable","checked":"[[ \"$(omarchy-default-browser)\" == \"edge\" ]]","action":"omarchy-default-browser edge"}, - "setup.default.browser.firefox": {"icon":"","label":"Firefox","when":"omarchy-cmd-present firefox","checked":"[[ \"$(omarchy-default-browser)\" == \"firefox\" ]]","action":"omarchy-default-browser firefox"}, - "setup.default.browser.zen": {"icon":"󰖟","label":"Zen","when":"omarchy-cmd-present zen-browser","checked":"[[ \"$(omarchy-default-browser)\" == \"zen\" ]]","action":"omarchy-default-browser zen"}, + "setup.default.browser.chromium": {"icon":"","label":"Chromium","checked":"[[ \"$(omarchy-default-browser)\" == \"chromium\" ]]","action":"omarchy-default-browser chromium"}, + "setup.default.browser.chrome": {"icon":"󰊯","label":"Chrome","checked":"[[ \"$(omarchy-default-browser)\" == \"chrome\" ]]","action":"omarchy-default-browser chrome"}, + "setup.default.browser.brave": {"icon":"󰖟","label":"Brave","checked":"[[ \"$(omarchy-default-browser)\" == \"brave\" ]]","action":"omarchy-default-browser brave"}, + "setup.default.browser.brave-origin": {"icon":"󰖟","label":"Brave Origin","checked":"[[ \"$(omarchy-default-browser)\" == \"brave-origin\" ]]","action":"omarchy-default-browser brave-origin"}, + "setup.default.browser.edge": {"icon":"󰇩","label":"Edge","checked":"[[ \"$(omarchy-default-browser)\" == \"edge\" ]]","action":"omarchy-default-browser edge"}, + "setup.default.browser.firefox": {"icon":"","label":"Firefox","checked":"[[ \"$(omarchy-default-browser)\" == \"firefox\" ]]","action":"omarchy-default-browser firefox"}, + "setup.default.browser.zen": {"icon":"󰖟","label":"Zen","checked":"[[ \"$(omarchy-default-browser)\" == \"zen\" ]]","action":"omarchy-default-browser zen"}, "setup.default.terminal": {"icon":"","label":"Terminal","title":"Default Terminal"}, - "setup.default.terminal.alacritty": {"icon":"","label":"Alacritty","when":"omarchy-cmd-present alacritty","checked":"[[ \"$(omarchy-default-terminal)\" == \"alacritty\" ]]","action":"omarchy-default-terminal alacritty"}, - "setup.default.terminal.foot": {"icon":"","label":"Foot","when":"omarchy-cmd-present foot","checked":"[[ \"$(omarchy-default-terminal)\" == \"foot\" ]]","action":"omarchy-default-terminal foot"}, - "setup.default.terminal.ghostty": {"icon":"","label":"Ghostty","when":"omarchy-cmd-present ghostty","checked":"[[ \"$(omarchy-default-terminal)\" == \"ghostty\" ]]","action":"omarchy-default-terminal ghostty"}, - "setup.default.terminal.kitty": {"icon":"","label":"Kitty","when":"omarchy-cmd-present kitty","checked":"[[ \"$(omarchy-default-terminal)\" == \"kitty\" ]]","action":"omarchy-default-terminal kitty"}, + "setup.default.terminal.alacritty": {"icon":"","label":"Alacritty","checked":"[[ \"$(omarchy-default-terminal)\" == \"alacritty\" ]]","action":"omarchy-default-terminal alacritty"}, + "setup.default.terminal.foot": {"icon":"","label":"Foot","checked":"[[ \"$(omarchy-default-terminal)\" == \"foot\" ]]","action":"omarchy-default-terminal foot"}, + "setup.default.terminal.ghostty": {"icon":"","label":"Ghostty","checked":"[[ \"$(omarchy-default-terminal)\" == \"ghostty\" ]]","action":"omarchy-default-terminal ghostty"}, + "setup.default.terminal.kitty": {"icon":"","label":"Kitty","checked":"[[ \"$(omarchy-default-terminal)\" == \"kitty\" ]]","action":"omarchy-default-terminal kitty"}, "setup.default.editor": {"icon":"","label":"Editor","title":"Default Editor"}, - "setup.default.editor.neovim": {"icon":"","label":"Neovim","when":"omarchy-cmd-present nvim","checked":"[[ \"$(omarchy-default-editor)\" == \"nvim\" ]]","action":"omarchy-default-editor nvim"}, - "setup.default.editor.vscode": {"icon":"","label":"VSCode","when":"omarchy-cmd-present code","checked":"[[ \"$(omarchy-default-editor)\" == \"code\" ]]","action":"omarchy-default-editor code"}, - "setup.default.editor.cursor": {"icon":"","label":"Cursor","when":"omarchy-cmd-present cursor","checked":"[[ \"$(omarchy-default-editor)\" == \"cursor\" ]]","action":"omarchy-default-editor cursor"}, - "setup.default.editor.zed": {"icon":"","label":"Zed","when":"omarchy-cmd-present zeditor","checked":"[[ \"$(omarchy-default-editor)\" == \"zeditor\" ]]","action":"omarchy-default-editor zed"}, - "setup.default.editor.sublime": {"icon":"","label":"Sublime Text","when":"omarchy-cmd-present sublime_text","checked":"[[ \"$(omarchy-default-editor)\" == \"sublime_text\" ]]","action":"omarchy-default-editor sublime_text"}, - "setup.default.editor.helix": {"icon":"","label":"Helix","when":"omarchy-cmd-present helix","checked":"[[ \"$(omarchy-default-editor)\" == \"helix\" ]]","action":"omarchy-default-editor helix"}, - "setup.default.editor.vim": {"icon":"","label":"Vim","when":"omarchy-cmd-present vim","checked":"[[ \"$(omarchy-default-editor)\" == \"vim\" ]]","action":"omarchy-default-editor vim"}, - "setup.default.editor.emacs": {"icon":"","label":"Emacs","when":"omarchy-cmd-present emacs","checked":"[[ \"$(omarchy-default-editor)\" == \"emacs\" ]]","action":"omarchy-default-editor emacs"}, + "setup.default.editor.neovim": {"icon":"","label":"Neovim","checked":"[[ \"$(omarchy-default-editor)\" == \"nvim\" ]]","action":"omarchy-default-editor nvim"}, + "setup.default.editor.vscode": {"icon":"","label":"VSCode","checked":"[[ \"$(omarchy-default-editor)\" == \"code\" ]]","action":"omarchy-default-editor code"}, + "setup.default.editor.cursor": {"icon":"","label":"Cursor","checked":"[[ \"$(omarchy-default-editor)\" == \"cursor\" ]]","action":"omarchy-default-editor cursor"}, + "setup.default.editor.zed": {"icon":"","label":"Zed","checked":"[[ \"$(omarchy-default-editor)\" == \"zeditor\" ]]","action":"omarchy-default-editor zed"}, + "setup.default.editor.sublime": {"icon":"","label":"Sublime Text","checked":"[[ \"$(omarchy-default-editor)\" == \"sublime_text\" ]]","action":"omarchy-default-editor sublime_text"}, + "setup.default.editor.helix": {"icon":"","label":"Helix","checked":"[[ \"$(omarchy-default-editor)\" == \"helix\" ]]","action":"omarchy-default-editor helix"}, + "setup.default.editor.vim": {"icon":"","label":"Vim","checked":"[[ \"$(omarchy-default-editor)\" == \"vim\" ]]","action":"omarchy-default-editor vim"}, + "setup.default.editor.emacs": {"icon":"","label":"Emacs","checked":"[[ \"$(omarchy-default-editor)\" == \"emacs\" ]]","action":"omarchy-default-editor emacs"}, "setup.plugin": {"icon":"󰐱","label":"Plugins","aliases":["plugin","plugins"]}, "setup.plugin.enable": {"icon":"󰄬","label":"Enable Plugin","action":"omarchy-menu-plugin enable"}, "setup.plugin.disable": {"icon":"󰅖","label":"Disable Plugin","action":"omarchy-menu-plugin disable"}, diff --git a/test/shell.d/chromium-copy-url-test.sh b/test/shell.d/chromium-copy-url-test.sh index 30f21cfd..6dad096f 100644 --- a/test/shell.d/chromium-copy-url-test.sh +++ b/test/shell.d/chromium-copy-url-test.sh @@ -71,9 +71,9 @@ jq -e --arg path "$ROOT/bin/omarchy-chromium-copy-url-host" ' ' "$native_manifest" >/dev/null || fail "copy-url native host manifest uses Omarchy host path and extension id" pass "copy-url native host installer registers the stable extension id" -# Chromium ships in the base packages, so it never goes through -# omarchy-install-browser, and a first install marks every migration as already -# applied. The user install has to register the host itself. +# Chromium ships in the base packages, so fresh installs do not go through +# omarchy-install-browser, and they mark every migration as already applied. +# The user install still has to register the host itself. grep -q 'user/chromium.sh' "$ROOT/install/user/all.sh" || fail "user install runs the Chromium native messaging host setup" diff --git a/test/shell.d/default-apps-test.sh b/test/shell.d/default-apps-test.sh new file mode 100755 index 00000000..aa07659d --- /dev/null +++ b/test/shell.d/default-apps-test.sh @@ -0,0 +1,274 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +mock_bin="$test_tmp/bin" +test_home="$test_tmp/home" +installed_dir="$test_tmp/installed" +install_log="$test_tmp/install-log" +terminal_log="$test_tmp/terminal-log" +notification_log="$test_tmp/notification-log" +setup_log="$test_tmp/setup-log" +browser_file="$test_tmp/browser" +mkdir -p "$mock_bin" "$test_home/.config" "$installed_dir" + +cat >"$mock_bin/omarchy-cmd-missing" <<'SH' +#!/bin/bash +[[ ! -e $OMARCHY_TEST_INSTALLED_DIR/$1 ]] +SH + +cat >"$mock_bin/omarchy-launch-floating-terminal-with-presentation" <<'SH' +#!/bin/bash +printf '%s\0' "$@" >"$OMARCHY_TEST_TERMINAL_LOG" +SH + +cat >"$mock_bin/omarchy-notification-send" <<'SH' +#!/bin/bash +printf '%s\0' "$@" >>"$OMARCHY_TEST_NOTIFICATION_LOG" +SH + +cat >"$mock_bin/omarchy-test-setup-call" <<'SH' +#!/bin/bash +printf '%s:%s\n' "${0##*/}" "$*" >>"$OMARCHY_TEST_SETUP_LOG" +[[ ${OMARCHY_TEST_SETUP_FAIL:-} != "${0##*/}" ]] +SH + +cat >"$mock_bin/sudo" <<'SH' +#!/bin/bash +printf 'sudo:%s\n' "$*" >>"$OMARCHY_TEST_SETUP_LOG" +[[ ${OMARCHY_TEST_SETUP_FAIL:-} != "sudo" ]] +SH + +cat >"$mock_bin/xdg-settings" <<'SH' +#!/bin/bash +case $1 in +get) [[ -f $OMARCHY_TEST_BROWSER_FILE ]] && cat "$OMARCHY_TEST_BROWSER_FILE" ;; +set) printf '%s\n' "$3" >"$OMARCHY_TEST_BROWSER_FILE" ;; +esac +SH + +cat >"$mock_bin/omarchy-test-installer" <<'SH' +#!/bin/bash +installer=${0##*/} + +if [[ $installer == "omarchy-install-browser" && ${OMARCHY_TEST_REAL_BROWSER_INSTALL:-false} == "true" ]]; then + exec "$ROOT/bin/omarchy-install-browser" "$@" +fi + +case $installer in +omarchy-pkg-add) + package=$1 + printf 'pkg:%s\n' "$package" >>"$OMARCHY_TEST_INSTALL_LOG" + case $package in + chromium) command=chromium ;; + cursor-bin) command=cursor ;; + sublime-text-4) command=sublime_text ;; + vim) command=vim ;; + neovim) command=nvim ;; + esac + ;; +omarchy-install-browser) + selection=$1 + printf 'browser:%s\n' "$selection" >>"$OMARCHY_TEST_INSTALL_LOG" + case $selection in + chromium) command=chromium ;; + chrome) command=google-chrome-stable ;; + brave) command=brave ;; + brave-origin) command=brave-origin ;; + edge) command=microsoft-edge-stable ;; + firefox) command=firefox ;; + zen) command=zen-browser ;; + esac + ;; +omarchy-install-terminal) + command=$1 + printf 'terminal:%s\n' "$command" >>"$OMARCHY_TEST_INSTALL_LOG" + ;; +omarchy-install-editor-*) + editor=${installer#omarchy-install-editor-} + printf 'editor:%s\n' "$editor" >>"$OMARCHY_TEST_INSTALL_LOG" + case $editor in + vscode) command=code ;; + zed) command=zeditor ;; + helix) command=helix ;; + emacs) command=emacs ;; + esac + ;; +esac + +[[ ${OMARCHY_TEST_INSTALL_FAIL:-false} != "true" ]] || exit 1 +touch "$OMARCHY_TEST_INSTALLED_DIR/$command" +SH + +for installer in \ + omarchy-pkg-add \ + omarchy-install-browser \ + omarchy-install-terminal \ + omarchy-install-editor-vscode \ + omarchy-install-editor-zed \ + omarchy-install-editor-helix \ + omarchy-install-editor-emacs; do + ln -s omarchy-test-installer "$mock_bin/$installer" +done +for setup_command in \ + omarchy-install-chromium-copy-url \ + omarchy-install-chromium-ytdlp \ + omarchy-theme-set-browser; do + ln -s omarchy-test-setup-call "$mock_bin/$setup_command" +done + +chmod +x "$mock_bin"/* + +export HOME="$test_home" +export PATH="$mock_bin:$ROOT/bin:$PATH" +export OMARCHY_PATH="$ROOT" +export OMARCHY_TEST_INSTALLED_DIR="$installed_dir" +export OMARCHY_TEST_INSTALL_LOG="$install_log" +export OMARCHY_TEST_TERMINAL_LOG="$terminal_log" +export OMARCHY_TEST_NOTIFICATION_LOG="$notification_log" +export OMARCHY_TEST_SETUP_LOG="$setup_log" +export OMARCHY_TEST_BROWSER_FILE="$browser_file" + +assert_missing_opens_installer() { + local type=$1 + local selection=$2 + + : >"$terminal_log" + "omarchy-default-$type" "$selection" + mapfile -d '' -t terminal_args <"$terminal_log" + [[ ${terminal_args[*]} == "omarchy-default-$type --install $selection" ]] || + fail "missing $selection opens its default installer in a terminal" +} + +browser_cases=( + 'chromium chromium browser:chromium' + 'chrome google-chrome-stable browser:chrome' + 'brave brave browser:brave' + 'brave-origin brave-origin browser:brave-origin' + 'edge microsoft-edge-stable browser:edge' + 'firefox firefox browser:firefox' + 'zen zen-browser browser:zen' +) + +terminal_cases=( + 'alacritty Alacritty.desktop' + 'foot foot.desktop' + 'ghostty com.mitchellh.ghostty.desktop' + 'kitty kitty.desktop' +) + +editor_cases=( + 'code code editor:vscode' + 'cursor cursor pkg:cursor-bin' + 'zed zeditor editor:zed' + 'sublime_text sublime_text pkg:sublime-text-4' + 'helix helix editor:helix' + 'vim vim pkg:vim' + 'emacs emacs editor:emacs' + 'nvim nvim pkg:neovim' +) + +for entry in "${browser_cases[@]}"; do + read -r selection command installer <<<"$entry" + assert_missing_opens_installer browser "$selection" +done +for entry in "${terminal_cases[@]}"; do + read -r selection desktop_id <<<"$entry" + assert_missing_opens_installer terminal "$selection" +done +for entry in "${editor_cases[@]}"; do + read -r selection command installer <<<"$entry" + assert_missing_opens_installer editor "$selection" +done +pass "missing defaults open visible installers for every supported app" + +for entry in "${browser_cases[@]}"; do + read -r selection command installer <<<"$entry" + rm -f "$installed_dir/$command" + : >"$install_log" + omarchy-default-browser --install "$selection" + [[ $(<"$install_log") == "$installer" ]] || fail "$selection uses its browser installer" + [[ $(omarchy-default-browser) == "$selection" ]] || fail "$selection becomes the default browser after installation" +done +pass "browser defaults install every missing browser before selection" + +: >"$install_log" +: >"$setup_log" +rm -f "$installed_dir/chromium" +OMARCHY_TEST_REAL_BROWSER_INSTALL=true omarchy-default-browser --install chromium >/dev/null +[[ $(<"$install_log") == "pkg:chromium" ]] || fail "Chromium browser installer installs the package" +[[ $(omarchy-default-browser) == "chromium" ]] || fail "Chromium becomes the default after its full installer succeeds" +cmp -s "$ROOT/config/chromium-flags.conf" "$test_home/.config/chromium-flags.conf" || + fail "Chromium browser installer copies the default flags" +grep -Fxq 'sudo:mkdir -p /etc/chromium/policies/managed' "$setup_log" || + fail "Chromium browser installer creates its policy directory" +grep -Fxq 'sudo:chmod a+rw /etc/chromium/policies/managed' "$setup_log" || + fail "Chromium browser installer makes its policy directory writable" +grep -Fxq 'omarchy-install-chromium-copy-url:' "$setup_log" || + fail "Chromium browser installer registers the Copy URL host" +grep -Fxq 'omarchy-install-chromium-ytdlp:' "$setup_log" || + fail "Chromium browser installer registers the yt-dlp host" +grep -Fxq 'omarchy-theme-set-browser:' "$setup_log" || + fail "Chromium browser installer applies the current theme" +pass "Chromium browser installer restores the complete Omarchy setup" + +omarchy-default-browser zen +rm -f "$installed_dir/chromium" +if OMARCHY_TEST_REAL_BROWSER_INSTALL=true OMARCHY_TEST_INSTALL_FAIL=true \ + omarchy-default-browser --install chromium >"$test_tmp/browser-package-failure" 2>&1; then + fail "failed Chromium package installation returns an error" +fi +[[ $(omarchy-default-browser) == "zen" ]] || fail "failed Chromium package installation preserves the default browser" +[[ ! -e $installed_dir/chromium ]] || fail "failed Chromium package installation does not mark it installed" +pass "failed Chromium package installation preserves the current default" + +if OMARCHY_TEST_REAL_BROWSER_INSTALL=true OMARCHY_TEST_SETUP_FAIL=sudo \ + omarchy-default-browser --install chromium >"$test_tmp/browser-install-failure" 2>&1; then + fail "failed Chromium setup returns an error" +fi +[[ $(omarchy-default-browser) == "zen" ]] || fail "failed Chromium setup preserves the default browser" +grep -Fq 'Installing Chromium' "$test_tmp/browser-install-failure" || + fail "failed Chromium setup keeps progress visible in the terminal" +pass "failed Chromium setup preserves the current default" + +for entry in "${terminal_cases[@]}"; do + read -r selection desktop_id <<<"$entry" + rm -f "$installed_dir/$selection" + : >"$install_log" + omarchy-default-terminal --install "$selection" + [[ $(<"$install_log") == "terminal:$selection" ]] || fail "$selection uses the terminal installer" + [[ $(tail -n 1 "$test_home/.config/xdg-terminals.list") == "$desktop_id" ]] || + fail "$selection becomes the default terminal after installation" +done +pass "terminal defaults install every missing terminal before selection" + +for entry in "${editor_cases[@]}"; do + read -r selection command installer <<<"$entry" + rm -f "$installed_dir/$command" + : >"$install_log" + omarchy-default-editor --install "$selection" + [[ $(<"$install_log") == "$installer" ]] || fail "$selection uses its editor installer" + [[ $(omarchy-default-editor) == "$command" ]] || fail "$selection becomes the default editor after installation" +done +pass "editor defaults install every missing editor before selection" + +: >"$install_log" +: >"$terminal_log" +omarchy-default-browser zen +omarchy-default-terminal kitty +omarchy-default-editor nvim +[[ ! -s $install_log && ! -s $terminal_log ]] || fail "installed defaults skip installation" +pass "installed defaults are selected immediately" + +previous_editor=$(omarchy-default-editor) +rm -f "$installed_dir/vim" +if OMARCHY_TEST_INSTALL_FAIL=true omarchy-default-editor --install vim >"$test_tmp/install-failure" 2>&1; then + fail "failed default installation returns an error" +fi +[[ $(omarchy-default-editor) == "$previous_editor" ]] || fail "failed installation preserves the default" +pass "failed installation preserves the current default" diff --git a/test/shell.d/menu-test.sh b/test/shell.d/menu-test.sh index 978987b8..ce7dae98 100644 --- a/test/shell.d/menu-test.sh +++ b/test/shell.d/menu-test.sh @@ -221,6 +221,19 @@ assertDeepEqual( ['Claude', 'Codex', 'Copilot', 'Crush', 'Gemini', 'Grok', 'omp', 'OpenCode', 'Pi'], 'menu sorts coding agents alphabetically' ) +const expectedDefaults = { + browser: ['Chromium', 'Chrome', 'Brave', 'Brave Origin', 'Edge', 'Firefox', 'Zen'], + terminal: ['Alacritty', 'Foot', 'Ghostty', 'Kitty'], + editor: ['Neovim', 'VSCode', 'Cursor', 'Zed', 'Sublime Text', 'Helix', 'Vim', 'Emacs'] +} +assert( + Object.entries(expectedDefaults).every(([type, labels]) => { + const entries = defaultItems.filter(item => item.parent === `setup.default.${type}`) + return entries.map(item => item.label).join('\0') === labels.join('\0') + && entries.every(item => !item.when) + }), + 'menu always exposes every supported browser, terminal, and editor under Defaults' +) assert(!defaultById['install.ai.crush'], 'menu removes Crush from Install > AI') assert( defaultById['setup.security.passwordless-sudo'].action.includes('omarchy-sudo-passwordless'),