wt 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #!/usr/bin/env bash
  2. set -e
  3. # Switch between git worktrees with speed.
  4. args=("$@")
  5. VERSION="0.2.4-fork"
  6. TMP_PATH=$(mktemp)
  7. BINARY_PATH=$(realpath "$0")
  8. VERSION_CACHE_FILE=${XDG_CACHE_HOME:-$HOME/.cache}/wt_latest_update_check.json
  9. JQ_URL="https://stedolan.github.io/jq/download"
  10. RELEASE_URL="https://github.com/mateusauler/git-worktree-switcher/releases/latest"
  11. RELEASE_API_URL="https://api.github.com/repos/mateusauler/git-worktree-switcher/releases/latest"
  12. CHANGE_DIRECTORY_PREFIX="changedir:"
  13. # Escape forward slash
  14. arg=${args[0]/\//\\\/}
  15. worktree_list_names() {
  16. git worktree list --porcelain 2> /dev/null | sed -n 's/^worktree\s*//p' | xargs -r -I{} basename {}
  17. }
  18. help_message() {
  19. echo -e "wt lets you switch between your git worktrees with speed.\n"
  20. echo "Usage:"
  21. echo -e "\twt: go to the main worktree"
  22. echo -e "\twt <worktree-name>: search for worktree names and change to that directory."
  23. echo -e "\twt names: list out only the git worktree names."
  24. echo -e "\twt update: update to the latest release of worktree switcher."
  25. echo -e "\twt version: show the CLI version."
  26. echo -e "\twt init <shell>: print the init script for <shell>."
  27. echo -e "\twt help: shows this help message."
  28. }
  29. download_latest_update() {
  30. download_url=$(curl -sL $RELEASE_API_URL | jq -r '.assets[0].browser_download_url')
  31. echo "Downloading latest version $fetched_tag_name"
  32. curl -sL -o "$TMP_PATH" "$download_url"
  33. echo "Updating to latest version..."
  34. chmod +x "$TMP_PATH"
  35. sudo mv "$TMP_PATH" "$BINARY_PATH"
  36. rm -f "$TMP_PATH"
  37. echo "You are using the latest version of worktree switcher: $fetched_tag_name"
  38. }
  39. check_release_version() {
  40. fetched_tag_name=$(check_and_cache_update)
  41. if [ "$fetched_tag_name" == $VERSION ]; then
  42. echo "You have the latest version of worktree switcher!"
  43. echo "Version: $VERSION"
  44. else
  45. download_latest_update
  46. fi
  47. }
  48. update() {
  49. if [ -z "$(command -v jq)" ]; then
  50. echo "jq is required for updating worktree switcher via this command."
  51. echo -e "Install jq:\n$JQ_URL.\n"
  52. echo -e "Or visit:\n$RELEASE_URL"
  53. else
  54. check_release_version
  55. fi
  56. }
  57. auto_check_update() {
  58. show_updates() {
  59. if [[ "$1" != "$VERSION" ]]; then
  60. echo "Version $1 available! Run 'wt update' to update." 1>&2
  61. echo "Currently running version $VERSION." 1>&2
  62. fi
  63. }
  64. if [[ -f "$VERSION_CACHE_FILE" ]]; then
  65. check_timestamp=$(jq -r '.timestamp' < "$VERSION_CACHE_FILE")
  66. latest_known_version=$(jq -r '.version' < "$VERSION_CACHE_FILE")
  67. one_day_ago_epoch=$(date -d '1 days ago' +%s)
  68. if (( check_timestamp > one_day_ago_epoch )); then
  69. show_updates "$latest_known_version"
  70. return 0
  71. fi
  72. fi
  73. fetched_tag_name=$(check_and_cache_update)
  74. show_updates "$fetched_tag_name"
  75. }
  76. check_and_cache_update() {
  77. echo "Checking for updates..." 1>&2
  78. fetched_tag_name=$(curl -sL $RELEASE_API_URL | jq -r '.tag_name')
  79. echo "$fetched_tag_name"
  80. mkdir -p "$(dirname "$VERSION_CACHE_FILE")"
  81. cat > "$VERSION_CACHE_FILE" <<EOF
  82. {
  83. "timestamp": "$(date +%s)",
  84. "version": "$fetched_tag_name"
  85. }
  86. EOF
  87. }
  88. get_dest_path="\$(echo \"\$result\" | awk '/^$CHANGE_DIRECTORY_PREFIX.*/ {sub(\"$CHANGE_DIRECTORY_PREFIX\", \"\"); print; exit}')"
  89. init_bash() {
  90. cat <<EOF
  91. wt() {
  92. result="\$($BINARY_PATH "\$@")"
  93. dest_path="$get_dest_path"
  94. if [[ -n "\$dest_path" ]]; then
  95. cd "\$dest_path" || return
  96. elif [[ -n \$result ]]; then
  97. echo "\$result"
  98. fi
  99. }
  100. EOF
  101. }
  102. init_fish() {
  103. cat <<EOF
  104. function wt
  105. set -l result "\$($BINARY_PATH \$argv)"
  106. set -l dest_path "$get_dest_path"
  107. if test -n "\$dest_path"
  108. cd "\$dest_path"
  109. else if test -n "\$result"
  110. echo "\$result"
  111. end
  112. end
  113. EOF
  114. }
  115. init() {
  116. shell="${args[1]}"
  117. if [[ -z $shell ]]; then
  118. echo "Please supply a shell."
  119. echo " eg. wt init bash"
  120. exit 1
  121. fi
  122. case "$shell" in
  123. bash|zsh)
  124. init_bash
  125. ;;
  126. fish)
  127. init_fish
  128. ;;
  129. *)
  130. echo "Unsupported shell: $shell"
  131. exit 1
  132. ;;
  133. esac
  134. }
  135. case "${args[0]}" in
  136. names)
  137. worktree_list_names
  138. ;;
  139. update)
  140. update
  141. ;;
  142. help)
  143. help_message
  144. ;;
  145. version)
  146. echo Version: $VERSION
  147. ;;
  148. init)
  149. init
  150. ;;
  151. *)
  152. auto_check_update
  153. directory=$(git worktree list --porcelain 2> /dev/null | sed -n '/'"${arg:-.}"'/{s/^worktree\s*//p;q}')
  154. ;;
  155. esac
  156. # If directory variable is not empty then change worktree
  157. if [ -z "$directory" ]; then
  158. :
  159. else
  160. echo "$CHANGE_DIRECTORY_PREFIX$directory"
  161. fi