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