#!/usr/bin/env bash # Nomarchy Atomic State Write Helper # Provides atomic JSON state updates with flock to prevent race conditions # # Usage: # nomarchy-state-write [--type string|bool|number|json] # nomarchy-state-write --file [--type ...] # # Examples: # nomarchy-state-write theme "nord" # nomarchy-state-write idle true --type bool # nomarchy-state-write hyprland '{"gaps_in": 5}' --type json # nomarchy-state-write --file /etc/nixos/state.json dns "Cloudflare" set -e # Default state file STATE_FILE="$HOME/.config/nomarchy/state.json" VALUE_TYPE="string" # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --file) STATE_FILE="$2" shift 2 ;; --type) VALUE_TYPE="$2" shift 2 ;; *) if [[ -z "$KEY" ]]; then KEY="$1" elif [[ -z "$VALUE" ]]; then VALUE="$1" fi shift ;; esac done if [[ -z "$KEY" ]] || [[ -z "$VALUE" ]]; then echo "Usage: nomarchy-state-write [--type string|bool|number|json]" echo " nomarchy-state-write --file [--type ...]" exit 1 fi # Ensure directory exists mkdir -p "$(dirname "$STATE_FILE")" # Initialize file if it doesn't exist [[ ! -f "$STATE_FILE" ]] && echo "{}" > "$STATE_FILE" # Create lock file path LOCK_FILE="${STATE_FILE}.lock" # Perform atomic update with flock ( flock -x 200 TMP_FILE=$(mktemp) trap "rm -f '$TMP_FILE'" EXIT case "$VALUE_TYPE" in string) jq --arg val "$VALUE" ".$KEY = \$val" "$STATE_FILE" > "$TMP_FILE" ;; bool) if [[ "$VALUE" == "true" ]] || [[ "$VALUE" == "false" ]]; then jq --argjson val "$VALUE" ".$KEY = \$val" "$STATE_FILE" > "$TMP_FILE" else echo "Error: Boolean value must be 'true' or 'false'" exit 1 fi ;; number) jq --argjson val "$VALUE" ".$KEY = \$val" "$STATE_FILE" > "$TMP_FILE" ;; json) jq --argjson val "$VALUE" ".$KEY = \$val" "$STATE_FILE" > "$TMP_FILE" ;; *) echo "Error: Unknown type '$VALUE_TYPE'. Use string, bool, number, or json." exit 1 ;; esac # Validate JSON before moving if jq empty "$TMP_FILE" 2>/dev/null; then mv "$TMP_FILE" "$STATE_FILE" else echo "Error: Failed to generate valid JSON" exit 1 fi ) 200>"$LOCK_FILE" # Clean up lock file rm -f "$LOCK_FILE"