install_udev.sh 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env sh
  2. # Copyright 2025 Nick Brassel (@tzarc)
  3. # SPDX-License-Identifier: GPL-2.0-or-later
  4. ################################################################################
  5. # Installs the latest QMK udev rules and qmk_id helper from
  6. # https://github.com/qmk/qmk_udev
  7. ################################################################################
  8. set -e
  9. nsudo() {
  10. if [ "$(id -u)" -ne 0 ]; then
  11. if [ -n "$(command -v sudo 2>/dev/null || true)" ]; then
  12. echo "sudo"
  13. elif [ -n "$(command -v doas 2>/dev/null || true)" ]; then
  14. echo "doas"
  15. else
  16. echo "Please install 'sudo' or 'doas' to continue." >&2
  17. exit 1
  18. fi
  19. fi
  20. true
  21. }
  22. download_url() {
  23. local url=$1
  24. local filename=${2:-$(basename "$url")}
  25. if [ -n "$(command -v curl 2>/dev/null || true)" ]; then
  26. curl -LSf -o "$filename" "$url"
  27. elif [ -n "$(command -v wget 2>/dev/null || true)" ]; then
  28. wget "-O$filename" "$url"
  29. else
  30. echo "Please install 'curl' or 'wget' to continue." >&2
  31. exit 1
  32. fi
  33. }
  34. github_api_call() {
  35. local url="$1"
  36. local token="${GITHUB_TOKEN:-${GH_TOKEN:-}}"
  37. if [ -n "${token:-}" ]; then
  38. if [ -n "$(command -v curl 2>/dev/null || true)" ]; then
  39. curl -fsSL -H "Authorization: token $token" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/$url"
  40. elif [ -n "$(command -v wget 2>/dev/null || true)" ]; then
  41. wget -q --header="Authorization: token $token" --header="Accept: application/vnd.github.v3+json" "https://api.github.com/$url" -O -
  42. fi
  43. else
  44. download_url "https://api.github.com/$url" -
  45. fi
  46. }
  47. fn_arch() {
  48. local arch_name=$(uname -m | tr 'A-Z' 'a-z')
  49. case "$arch_name" in
  50. *arm64* | *aarch64*)
  51. echo ARM64
  52. ;;
  53. *riscv64*)
  54. echo RV64
  55. ;;
  56. *x86_64* | *x64*)
  57. echo X64
  58. ;;
  59. *)
  60. echo "Unsupported architecture: $arch_name" >&2
  61. exit 1
  62. ;;
  63. esac
  64. }
  65. if [ "$(uname -s 2>/dev/null || true)" != "Linux" ]; then
  66. echo "This script is only intended for Linux." >&2
  67. exit 1
  68. fi
  69. # Create a temporary directory for downloads
  70. tmpdir=$(mktemp -d)
  71. trap 'rm -rf "$tmpdir"' EXIT
  72. # Get the latest qmk_udev release
  73. echo "Fetching latest qmk_udev release..." >&2
  74. latest_release=$(github_api_call repos/qmk/qmk_udev/releases/latest | grep -oE '"tag_name": "[^"]+' | grep -oE '[^"]+$')
  75. if [ -z "$latest_release" ]; then
  76. echo "Could not determine latest qmk_udev release." >&2
  77. exit 1
  78. fi
  79. echo "Using qmk_udev release: $latest_release" >&2
  80. release_base="https://github.com/qmk/qmk_udev/releases/download/$latest_release"
  81. # Download the udev rules file and architecture-appropriate qmk_id binary
  82. download_url "$release_base/50-qmk.rules" "$tmpdir/50-qmk.rules"
  83. download_url "$release_base/qmk_id-linux$(fn_arch)" "$tmpdir/qmk_id"
  84. # Remove existing QMK udev rules and qmk_id helpers from all standard locations
  85. echo "Removing existing QMK udev rules and helpers..." >&2
  86. for dir in /etc/udev/rules.d /run/udev/rules.d /usr/lib/udev/rules.d /usr/local/lib/udev/rules.d /lib/udev/rules.d; do
  87. if [ -d "$dir" ]; then
  88. for f in "$dir"/*-qmk.rules; do
  89. [ -e "$f" ] && echo "Removing $f" >&2 && $(nsudo) rm -f "$f"
  90. done
  91. fi
  92. done
  93. for dir in /usr/lib/udev /usr/local/lib/udev /lib/udev; do
  94. [ -e "$dir/qmk_id" ] && echo "Removing $dir/qmk_id" >&2 && $(nsudo) rm -f "$dir/qmk_id"
  95. done
  96. # Install qmk_id binary and udev rules
  97. echo "Installing /usr/lib/udev/qmk_id ..." >&2
  98. $(nsudo) install -d -m 0755 /usr/lib/udev
  99. $(nsudo) install -m 0755 "$tmpdir/qmk_id" /usr/lib/udev/qmk_id
  100. echo "Installing /etc/udev/rules.d/50-qmk.rules ..." >&2
  101. $(nsudo) install -d -m 0755 /etc/udev/rules.d
  102. $(nsudo) install -m 0644 "$tmpdir/50-qmk.rules" /etc/udev/rules.d/50-qmk.rules
  103. # Reload udev rules
  104. if command -v udevadm >/dev/null 2>&1; then
  105. echo "Reloading udev rules..." >&2
  106. $(nsudo) udevadm control --reload-rules || true
  107. $(nsudo) udevadm trigger || true
  108. else
  109. echo "udevadm not found, skipping udev rules reload." >&2
  110. fi
  111. echo "Done." >&2