install 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. APP=opencode
  4. RED='\033[0;31m'
  5. GREEN='\033[0;32m'
  6. YELLOW='\033[1;33m'
  7. ORANGE='\033[38;2;255;140;0m'
  8. NC='\033[0m' # No Color
  9. requested_version=${VERSION:-}
  10. os=$(uname -s | tr '[:upper:]' '[:lower:]')
  11. if [[ "$os" == "darwin" ]]; then
  12. os="darwin"
  13. fi
  14. arch=$(uname -m)
  15. if [[ "$arch" == "aarch64" ]]; then
  16. arch="arm64"
  17. elif [[ "$arch" == "x86_64" ]]; then
  18. arch="x64"
  19. fi
  20. filename="$APP-$os-$arch.zip"
  21. case "$filename" in
  22. *"-linux-"*)
  23. [[ "$arch" == "x64" || "$arch" == "arm64" ]] || exit 1
  24. ;;
  25. *"-darwin-"*)
  26. [[ "$arch" == "x64" || "$arch" == "arm64" ]] || exit 1
  27. ;;
  28. *"-windows-"*)
  29. [[ "$arch" == "x64" ]] || exit 1
  30. ;;
  31. *)
  32. echo "${RED}Unsupported OS/Arch: $os/$arch${NC}"
  33. exit 1
  34. ;;
  35. esac
  36. # Determine installation directory with priority order
  37. if [ -n "${OPENCODE_INSTALL_DIR:-}" ]; then
  38. INSTALL_DIR="$OPENCODE_INSTALL_DIR"
  39. elif [ -n "${XDG_BIN_DIR:-}" ]; then
  40. INSTALL_DIR="$XDG_BIN_DIR"
  41. elif [ -d "$HOME/bin" ] || mkdir -p "$HOME/bin" 2>/dev/null; then
  42. INSTALL_DIR="$HOME/bin"
  43. else
  44. INSTALL_DIR="$HOME/.opencode/bin"
  45. fi
  46. print_message() {
  47. local level=$1
  48. local message=$2
  49. local color=""
  50. case $level in
  51. info) color="${GREEN}" ;;
  52. warning) color="${YELLOW}" ;;
  53. error) color="${RED}" ;;
  54. esac
  55. echo -e "${color}${message}${NC}"
  56. }
  57. mkdir -p "$INSTALL_DIR"
  58. print_message info "Installing to: ${YELLOW}$INSTALL_DIR${GREEN}"
  59. if [ -z "$requested_version" ]; then
  60. url="https://github.com/sst/opencode/releases/latest/download/$filename"
  61. specific_version=$(curl -s https://api.github.com/repos/sst/opencode/releases/latest | awk -F'"' '/"tag_name": "/ {gsub(/^v/, "", $4); print $4}')
  62. if [[ $? -ne 0 || -z "$specific_version" ]]; then
  63. echo "${RED}Failed to fetch version information${NC}"
  64. exit 1
  65. fi
  66. else
  67. url="https://github.com/sst/opencode/releases/download/v${requested_version}/$filename"
  68. specific_version=$requested_version
  69. fi
  70. check_version() {
  71. if command -v opencode >/dev/null 2>&1; then
  72. opencode_path=$(which opencode)
  73. ## TODO: check if version is installed
  74. # installed_version=$(opencode version)
  75. installed_version="0.0.1"
  76. installed_version=$(echo $installed_version | awk '{print $2}')
  77. if [[ "$installed_version" != "$specific_version" ]]; then
  78. print_message info "Installed version: ${YELLOW}$installed_version."
  79. else
  80. print_message info "Version ${YELLOW}$specific_version${GREEN} already installed"
  81. exit 0
  82. fi
  83. fi
  84. }
  85. download_and_install() {
  86. print_message info "Downloading ${ORANGE}opencode ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..."
  87. mkdir -p opencodetmp && cd opencodetmp
  88. curl -# -L -o "$filename" "$url"
  89. unzip -q "$filename"
  90. mv opencode "$INSTALL_DIR"
  91. cd .. && rm -rf opencodetmp
  92. }
  93. check_version
  94. download_and_install
  95. add_to_path() {
  96. local config_file=$1
  97. local command=$2
  98. if grep -Fxq "$command" "$config_file"; then
  99. print_message info "Command already exists in $config_file, skipping write."
  100. elif [[ -w $config_file ]]; then
  101. echo -e "\n# opencode" >> "$config_file"
  102. echo "$command" >> "$config_file"
  103. print_message info "Successfully added ${ORANGE}opencode ${GREEN}to \$PATH in $config_file"
  104. else
  105. print_message warning "Manually add the directory to $config_file (or similar):"
  106. print_message info " $command"
  107. fi
  108. }
  109. XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
  110. current_shell=$(basename "$SHELL")
  111. case $current_shell in
  112. fish)
  113. config_files="$HOME/.config/fish/config.fish"
  114. ;;
  115. zsh)
  116. config_files="$HOME/.zshrc $HOME/.zshenv $XDG_CONFIG_HOME/zsh/.zshrc $XDG_CONFIG_HOME/zsh/.zshenv"
  117. ;;
  118. bash)
  119. config_files="$HOME/.bashrc $HOME/.bash_profile $HOME/.profile $XDG_CONFIG_HOME/bash/.bashrc $XDG_CONFIG_HOME/bash/.bash_profile"
  120. ;;
  121. ash)
  122. config_files="$HOME/.ashrc $HOME/.profile /etc/profile"
  123. ;;
  124. sh)
  125. config_files="$HOME/.ashrc $HOME/.profile /etc/profile"
  126. ;;
  127. *)
  128. # Default case if none of the above matches
  129. config_files="$HOME/.bashrc $HOME/.bash_profile $XDG_CONFIG_HOME/bash/.bashrc $XDG_CONFIG_HOME/bash/.bash_profile"
  130. ;;
  131. esac
  132. config_file=""
  133. for file in $config_files; do
  134. if [[ -f $file ]]; then
  135. config_file=$file
  136. break
  137. fi
  138. done
  139. if [[ -z $config_file ]]; then
  140. print_message error "No config file found for $current_shell. Checked files: ${config_files[@]}"
  141. exit 1
  142. fi
  143. if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
  144. case $current_shell in
  145. fish)
  146. add_to_path "$config_file" "fish_add_path $INSTALL_DIR"
  147. ;;
  148. zsh)
  149. add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
  150. ;;
  151. bash)
  152. add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
  153. ;;
  154. ash)
  155. add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
  156. ;;
  157. sh)
  158. add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
  159. ;;
  160. *)
  161. export PATH=$INSTALL_DIR:$PATH
  162. print_message warning "Manually add the directory to $config_file (or similar):"
  163. print_message info " export PATH=$INSTALL_DIR:\$PATH"
  164. ;;
  165. esac
  166. fi
  167. if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then
  168. echo "$INSTALL_DIR" >> $GITHUB_PATH
  169. print_message info "Added $INSTALL_DIR to \$GITHUB_PATH"
  170. fi