From 8862fb22bda429e66c29bc4d41dd61a45838be66 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 18 Jul 2026 10:08:25 -0700 Subject: [PATCH] Use Omarchy command helpers consistently --- bin/omarchy-capture-screenrecording | 6 +++--- bin/omarchy-dns | 16 +++++----------- bin/omarchy-first-run | 6 +++--- bin/omarchy-hibernation-setup | 2 +- bin/omarchy-hw-hybrid-gpu | 2 +- bin/omarchy-launch-screensaver | 13 +++++++------ bin/omarchy-migrate-notify | 2 +- bin/omarchy-plugin | 4 ++-- bin/omarchy-plugin-catalog | 2 +- bin/omarchy-plugin-clone | 2 +- bin/omarchy-plugin-validate | 2 +- bin/omarchy-refresh-plymouth | 4 ++-- bin/omarchy-remove-gaming-geforce-now | 2 +- bin/omarchy-remove-launcher-entry | 2 +- bin/omarchy-snapshot | 2 +- bin/omarchy-system-lock | 2 +- bin/omarchy-system-sleep-monitor | 6 ++---- bin/omarchy-tui-remove-all | 2 +- bin/omarchy-update | 2 +- bin/omarchy-upload-log | 2 +- bin/omarchy-webapp-remove-all | 2 +- bin/omarchy-windows-vm | 2 +- test/shell.d/bin-style-test.sh | 15 +++++++++++++++ 23 files changed, 54 insertions(+), 46 deletions(-) create mode 100644 test/shell.d/bin-style-test.sh diff --git a/bin/omarchy-capture-screenrecording b/bin/omarchy-capture-screenrecording index 478c93f7..df3b2808 100755 --- a/bin/omarchy-capture-screenrecording +++ b/bin/omarchy-capture-screenrecording @@ -22,7 +22,7 @@ OUTPUT_DIR="${OMARCHY_SCREENRECORD_DIR:-${XDG_VIDEOS_DIR:-$HOME/Videos}}" if [[ ! -d $OUTPUT_DIR ]]; then - notify-send "Screen recording directory does not exist: $OUTPUT_DIR" -u critical -t 3000 + omarchy-notification-send -u critical -t 3000 "Screen recording directory does not exist: $OUTPUT_DIR" exit 1 fi @@ -65,7 +65,7 @@ start_webcam_overlay() { if [[ -z $WEBCAM_DEVICE ]]; then WEBCAM_DEVICE=$(v4l2-ctl --list-devices 2>/dev/null | grep -m1 "^[[:space:]]*/dev/video" | tr -d '\t') if [[ -z $WEBCAM_DEVICE ]]; then - notify-send "No webcam devices found" -u critical -t 3000 + omarchy-notification-send -u critical -t 3000 "No webcam devices found" return 1 fi fi @@ -200,7 +200,7 @@ stop_screenrecording() { if pgrep -f "^gpu-screen-recorder" >/dev/null; then pkill -9 -f "^gpu-screen-recorder" - notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000 + omarchy-notification-send -u critical -t 5000 "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." else finalize_recording local filename=$(cat "$RECORDING_FILE" 2>/dev/null) diff --git a/bin/omarchy-dns b/bin/omarchy-dns index 61b97ca5..078b2a19 100755 --- a/bin/omarchy-dns +++ b/bin/omarchy-dns @@ -29,13 +29,7 @@ provider_from_arg() { } self_path() { - local self="${BASH_SOURCE[0]}" - - if [[ $self != /* ]]; then - self=$(command -v -- "$self") - fi - - readlink -f "$self" + readlink -f "$OMARCHY_PATH/bin/${BASH_SOURCE[0]##*/}" } require_root() { @@ -43,7 +37,7 @@ require_root() { return fi - if ! command -v pkexec >/dev/null; then + if omarchy-cmd-missing pkexec; then echo "Error: pkexec is required to change DNS settings." >&2 exit 1 fi @@ -156,7 +150,7 @@ set_connection_dns() { local ipv4_dns="${1:-}" local ipv6_dns="${2:-}" - command -v nmcli >/dev/null 2>&1 || return 0 + omarchy-cmd-present nmcli || return 0 while IFS=: read -r uuid type; do [[ -n $uuid ]] || continue @@ -174,7 +168,7 @@ set_connection_dns() { clear_connection_dns() { local uuid type - command -v nmcli >/dev/null 2>&1 || return 0 + omarchy-cmd-present nmcli || return 0 while IFS=: read -r uuid type; do [[ -n $uuid ]] || continue @@ -192,7 +186,7 @@ clear_connection_dns() { reapply_active_dns_connections() { local device type state - command -v nmcli >/dev/null 2>&1 || return 0 + omarchy-cmd-present nmcli || return 0 while IFS=: read -r device type state; do [[ -n $device && $state == connected ]] || continue diff --git a/bin/omarchy-first-run b/bin/omarchy-first-run index 3a6a9710..b95849d3 100755 --- a/bin/omarchy-first-run +++ b/bin/omarchy-first-run @@ -54,12 +54,12 @@ log_first_run() { } notification_server_ready() { - if command -v gdbus >/dev/null 2>&1; then + if omarchy-cmd-present gdbus; then gdbus call --session \ --dest org.freedesktop.Notifications \ --object-path /org/freedesktop/Notifications \ --method org.freedesktop.Notifications.GetServerInformation >/dev/null 2>&1 - elif command -v busctl >/dev/null 2>&1; then + elif omarchy-cmd-present busctl; then busctl --user call \ org.freedesktop.Notifications \ /org/freedesktop/Notifications \ @@ -71,7 +71,7 @@ notification_server_ready() { } wait_for_notifications() { - command -v omarchy-shell >/dev/null || return 0 + omarchy-cmd-present omarchy-shell || return 0 for _ in {1..100}; do if omarchy-shell notifications ping >/dev/null 2>&1 && notification_server_ready; then diff --git a/bin/omarchy-hibernation-setup b/bin/omarchy-hibernation-setup index 775c4e2c..7bc57246 100755 --- a/bin/omarchy-hibernation-setup +++ b/bin/omarchy-hibernation-setup @@ -21,7 +21,7 @@ fi # When --no-rebuild is set, the caller is responsible for the UKI rebuild # (e.g. running before limine-mkinitcpio-hook is installed during initial # install), so we only require limine-mkinitcpio when we'd invoke it ourselves. -if ! $NO_REBUILD && ! command -v limine-mkinitcpio &>/dev/null; then +if ! $NO_REBUILD && omarchy-cmd-missing limine-mkinitcpio; then echo "Skipping hibernation setup (requires Limine bootloader)" exit 0 fi diff --git a/bin/omarchy-hw-hybrid-gpu b/bin/omarchy-hw-hybrid-gpu index 7a960c79..13fd15cd 100755 --- a/bin/omarchy-hw-hybrid-gpu +++ b/bin/omarchy-hw-hybrid-gpu @@ -2,7 +2,7 @@ # omarchy:summary=Detect whether the system has an active hybrid GPU configuration -if command -v supergfxctl &>/dev/null; then +if omarchy-cmd-present supergfxctl; then supergfxctl -s 2>/dev/null | grep -qw Hybrid else (($(lspci | grep -cE 'VGA|3D|Display') >= 2)) diff --git a/bin/omarchy-launch-screensaver b/bin/omarchy-launch-screensaver index 846d7801..3f8b82f8 100755 --- a/bin/omarchy-launch-screensaver +++ b/bin/omarchy-launch-screensaver @@ -2,7 +2,7 @@ # omarchy:summary=Launch the Omarchy screensaver in the default terminal on the system with the correct font configuration. -if ! command -v tte &>/dev/null; then +if omarchy-cmd-missing tte; then exit 1 fi @@ -22,7 +22,8 @@ hypr_focus_monitor() { } hypr_exec() { - local command="$1" + local command + printf -v command '%q ' "$@" hyprctl dispatch "hl.dsp.exec_cmd([[$command]])" >/dev/null 2>&1 || hyprctl dispatch exec -- bash -lc "$command" >/dev/null } @@ -32,16 +33,16 @@ for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do case $terminal in *Alacritty*) - hypr_exec "alacritty --class=org.omarchy.screensaver --config-file $OMARCHY_PATH/default/alacritty/screensaver.toml -e omarchy-screensaver" + hypr_exec alacritty --class=org.omarchy.screensaver --config-file "$OMARCHY_PATH/default/alacritty/screensaver.toml" -e omarchy-screensaver ;; *ghostty*) - hypr_exec "ghostty --class=org.omarchy.screensaver --config-file=$OMARCHY_PATH/default/ghostty/screensaver --font-size=18 -e omarchy-screensaver" + hypr_exec ghostty --class=org.omarchy.screensaver --config-file="$OMARCHY_PATH/default/ghostty/screensaver" --font-size=18 -e omarchy-screensaver ;; *foot*) - hypr_exec "foot --app-id=org.omarchy.screensaver --config=\"$OMARCHY_PATH/default/foot/screensaver.ini\" -e omarchy-screensaver" + hypr_exec foot --app-id=org.omarchy.screensaver --config="$OMARCHY_PATH/default/foot/screensaver.ini" -e omarchy-screensaver ;; *kitty*) - hypr_exec "kitty --class=org.omarchy.screensaver --override font_size=18 --override window_padding_width=0 -e omarchy-screensaver" + hypr_exec kitty --class=org.omarchy.screensaver --override font_size=18 --override window_padding_width=0 -e omarchy-screensaver ;; *) omarchy-notification-send -g ✋ "Screensaver only runs in Alacritty, Foot, Ghostty, or Kitty" diff --git a/bin/omarchy-migrate-notify b/bin/omarchy-migrate-notify index 3fb99788..d503560b 100755 --- a/bin/omarchy-migrate-notify +++ b/bin/omarchy-migrate-notify @@ -15,7 +15,7 @@ fi notify_command=$(printf 'if [[ -n $(omarchy-notification-send -u critical -g  "Run Omarchy Migrations" %q -a) ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-migrate; fi' "$message") -if command -v systemd-run >/dev/null 2>&1; then +if omarchy-cmd-present systemd-run; then unit="omarchy-migrations-notification-$(date +%Y%m%d%H%M%S)" systemd-run --user --scope --unit="$unit" bash -lc "$notify_command" >/dev/null 2>&1 && exit 0 fi diff --git a/bin/omarchy-plugin b/bin/omarchy-plugin index 339a7d01..9955ce55 100755 --- a/bin/omarchy-plugin +++ b/bin/omarchy-plugin @@ -52,7 +52,7 @@ fail() { } require_command() { - command -v "$1" >/dev/null 2>&1 || fail "$1 is required" + omarchy-cmd-present "$1" || fail "$1 is required" } interactive() { @@ -283,7 +283,7 @@ update_one() { if (( ! ASSUME_YES )); then echo "Changes for $id:" - if command -v delta >/dev/null 2>&1; then + if omarchy-cmd-present delta; then git -C "$dir" diff HEAD FETCH_HEAD | delta --paging=never else git -C "$dir" diff HEAD FETCH_HEAD diff --git a/bin/omarchy-plugin-catalog b/bin/omarchy-plugin-catalog index c526be21..437899d2 100755 --- a/bin/omarchy-plugin-catalog +++ b/bin/omarchy-plugin-catalog @@ -15,7 +15,7 @@ set -o pipefail OMARCHY_PATH="${OMARCHY_PATH:-}" -command -v jq >/dev/null 2>&1 || { echo "omarchy-plugin-catalog: jq is required" >&2; exit 1; } +omarchy-cmd-present jq || { echo "omarchy-plugin-catalog: jq is required" >&2; exit 1; } paths=() diff --git a/bin/omarchy-plugin-clone b/bin/omarchy-plugin-clone index 7ed4f7b9..173c3fd1 100755 --- a/bin/omarchy-plugin-clone +++ b/bin/omarchy-plugin-clone @@ -15,7 +15,7 @@ fail() { } require_command() { - command -v "$1" >/dev/null 2>&1 || fail "$1 is required" + omarchy-cmd-present "$1" || fail "$1 is required" } require_omarchy_path() { diff --git a/bin/omarchy-plugin-validate b/bin/omarchy-plugin-validate index d309a4a5..43890574 100755 --- a/bin/omarchy-plugin-validate +++ b/bin/omarchy-plugin-validate @@ -28,7 +28,7 @@ USAGE exit 0 fi -command -v jq >/dev/null 2>&1 || fail "jq is required" +omarchy-cmd-present jq || fail "jq is required" PLUGIN_DIR="${1:-}" [[ -n $PLUGIN_DIR && -d $PLUGIN_DIR ]] || fail "plugin folder not found: ${PLUGIN_DIR:-}" diff --git a/bin/omarchy-refresh-plymouth b/bin/omarchy-refresh-plymouth index 07feaf78..58042dba 100755 --- a/bin/omarchy-refresh-plymouth +++ b/bin/omarchy-refresh-plymouth @@ -3,10 +3,10 @@ # omarchy:summary=Overwrite the user config for the Plymouth drive decryption and boot sequence with the Omarchy default and rebuild it. # omarchy:requires-sudo=true -sudo cp -r $OMARCHY_PATH/default/plymouth/* /usr/share/plymouth/themes/omarchy/ +sudo cp -r "$OMARCHY_PATH/default/plymouth/." /usr/share/plymouth/themes/omarchy/ sudo plymouth-set-default-theme omarchy -if command -v limine-mkinitcpio &>/dev/null; then +if omarchy-cmd-present limine-mkinitcpio; then sudo limine-mkinitcpio else sudo mkinitcpio -P diff --git a/bin/omarchy-remove-gaming-geforce-now b/bin/omarchy-remove-gaming-geforce-now index c7d37444..19a6ecd4 100755 --- a/bin/omarchy-remove-gaming-geforce-now +++ b/bin/omarchy-remove-gaming-geforce-now @@ -6,7 +6,7 @@ set -e -if command -v flatpak >/dev/null && flatpak info com.nvidia.geforcenow &>/dev/null; then +if omarchy-cmd-present flatpak && flatpak info com.nvidia.geforcenow &>/dev/null; then flatpak uninstall -y --delete-data com.nvidia.geforcenow fi diff --git a/bin/omarchy-remove-launcher-entry b/bin/omarchy-remove-launcher-entry index a833de0f..a07fa31b 100755 --- a/bin/omarchy-remove-launcher-entry +++ b/bin/omarchy-remove-launcher-entry @@ -91,7 +91,7 @@ if package_name="$(pacman -Qqo "$desktop_file" 2>/dev/null | head -1)" && [[ -n exec omarchy-launch-floating-terminal-with-presentation "echo Uninstalling $quoted_display...; sudo pacman -Rns $quoted_package" fi -if command -v flatpak >/dev/null 2>&1 && flatpak info "${desktop_file_name%.desktop}" >/dev/null 2>&1; then +if omarchy-cmd-present flatpak && flatpak info "${desktop_file_name%.desktop}" >/dev/null 2>&1; then flatpak_id="${desktop_file_name%.desktop}" quoted_flatpak="$(printf '%q' "$flatpak_id")" exec omarchy-launch-floating-terminal-with-presentation "flatpak uninstall $quoted_flatpak" diff --git a/bin/omarchy-snapshot b/bin/omarchy-snapshot index 27c1b7de..f173f1e1 100755 --- a/bin/omarchy-snapshot +++ b/bin/omarchy-snapshot @@ -13,7 +13,7 @@ if [[ -z $COMMAND ]]; then exit 1 fi -if ! command -v snapper &>/dev/null; then +if omarchy-cmd-missing snapper; then exit 127 # omarchy-update can use this to just ignore if snapper is not available fi diff --git a/bin/omarchy-system-lock b/bin/omarchy-system-lock index bcad2452..d9865e9f 100755 --- a/bin/omarchy-system-lock +++ b/bin/omarchy-system-lock @@ -12,7 +12,7 @@ hyprctl switchxkblayout all 0 > /dev/null 2>&1 # Ensure 1password is locked. Use timeout because `1password --lock` can # otherwise leave a full Electron helper tree running after each lock. -if pgrep -x "1password" >/dev/null && command -v 1password >/dev/null 2>&1; then +if pgrep -x "1password" >/dev/null && omarchy-cmd-present 1password; then ( flock -n 9 || exit 0 timeout --kill-after=1s 3s 1password --lock >/dev/null 2>&1 || true diff --git a/bin/omarchy-system-sleep-monitor b/bin/omarchy-system-sleep-monitor index bd343b01..64d8d1f2 100755 --- a/bin/omarchy-system-sleep-monitor +++ b/bin/omarchy-system-sleep-monitor @@ -8,8 +8,7 @@ monitor_command='exec dbus-monitor --system "type='\''signal'\'',sender='\''org. consume_sleep_events() { local line sleep_lock - sleep_lock=$(command -v omarchy-system-sleep-lock || true) - sleep_lock=${sleep_lock:-/usr/bin/omarchy-system-sleep-lock} + sleep_lock="$OMARCHY_PATH/bin/omarchy-system-sleep-lock" while IFS= read -r line; do if [[ $line == *"boolean true"* ]]; then @@ -24,8 +23,7 @@ if [[ ${1:-} == "--consume" ]]; then exit 0 fi -sleep_monitor=$(command -v omarchy-system-sleep-monitor || true) -sleep_monitor=${sleep_monitor:-/usr/bin/omarchy-system-sleep-monitor} +sleep_monitor="$OMARCHY_PATH/bin/omarchy-system-sleep-monitor" exec systemd-inhibit \ --what=sleep \ diff --git a/bin/omarchy-tui-remove-all b/bin/omarchy-tui-remove-all index f947a198..8ae511b8 100755 --- a/bin/omarchy-tui-remove-all +++ b/bin/omarchy-tui-remove-all @@ -30,7 +30,7 @@ for file in "${tui_desktop_files[@]}"; do rm -f "$ICON_DIR/$icon_name.png" "$ICON_DIR/$app_name.png" "$OLD_ICON_DIR/$app_name.png" done -if command -v update-desktop-database &>/dev/null; then +if omarchy-cmd-present update-desktop-database; then update-desktop-database "$APP_DIR" &>/dev/null || true fi diff --git a/bin/omarchy-update b/bin/omarchy-update index ed009bd7..22d9edbb 100755 --- a/bin/omarchy-update +++ b/bin/omarchy-update @@ -38,7 +38,7 @@ update_disabled_idle=0 sleep_inhibit_pid="" disable_sleep_for_update() { - command -v systemd-inhibit >/dev/null 2>&1 || return 0 + omarchy-cmd-present systemd-inhibit || return 0 systemd-inhibit \ --what=sleep:idle \ diff --git a/bin/omarchy-upload-log b/bin/omarchy-upload-log index 2bbafac7..134d9174 100755 --- a/bin/omarchy-upload-log +++ b/bin/omarchy-upload-log @@ -9,7 +9,7 @@ TEMP_LOG="/tmp/upload-log.txt" SYSTEM_INFO="/tmp/system-info.txt" # Get system information if fastfetch is available -if command -v fastfetch >/dev/null 2>&1; then +if omarchy-cmd-present fastfetch; then { echo "=========================================" echo "SYSTEM INFORMATION" diff --git a/bin/omarchy-webapp-remove-all b/bin/omarchy-webapp-remove-all index 1754c4ee..58255a65 100755 --- a/bin/omarchy-webapp-remove-all +++ b/bin/omarchy-webapp-remove-all @@ -30,7 +30,7 @@ for file in "${webapp_desktop_files[@]}"; do rm -f "$ICON_DIR/$icon_name.png" "$ICON_DIR/$app_name.png" "$OLD_ICON_DIR/$app_name.png" done -if command -v update-desktop-database &>/dev/null; then +if omarchy-cmd-present update-desktop-database; then update-desktop-database "$APP_DIR" &>/dev/null || true fi diff --git a/bin/omarchy-windows-vm b/bin/omarchy-windows-vm index 67bf7a15..2a2cf887 100755 --- a/bin/omarchy-windows-vm +++ b/bin/omarchy-windows-vm @@ -294,7 +294,7 @@ launch_windows() { echo "❌ Failed to start Windows VM!" echo " Try checking: omarchy-windows-vm status" echo " View logs: docker logs omarchy-windows" - notify-send -u critical "Windows VM" "Failed to start Windows VM" + omarchy-notification-send -u critical "Windows VM" "Failed to start Windows VM" exit 1 fi diff --git a/test/shell.d/bin-style-test.sh b/test/shell.d/bin-style-test.sh new file mode 100644 index 00000000..e7824e9b --- /dev/null +++ b/test/shell.d/bin-style-test.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +raw_command_checks=$(rg -l 'command -v' "$ROOT/bin" \ + | rg -v '/omarchy-(cmd-|pkg-|upgrade-to-quattro)' || true) +[[ -z $raw_command_checks ]] || fail "bin commands use command helpers" "$raw_command_checks" +pass "bin commands use command helpers" + +raw_notifications=$(rg -l -P '^[[:space:]]*[^#[:space:]].*\bnotify-send\b' "$ROOT/bin" \ + | rg -v '/omarchy-notification-send$' || true) +[[ -z $raw_notifications ]] || fail "bin commands use the notification helper" "$raw_notifications" +pass "bin commands use the notification helper"