1#!/usr/bin/env bash
2set -euo pipefail
3APP=opencode
4
5RED='\033[0;31m'
6GREEN='\033[0;32m'
7YELLOW='\033[1;33m'
8ORANGE='\033[38;2;255;140;0m'
9NC='\033[0m' # No Color
10
11requested_version=${VERSION:-}
12
13os=$(uname -s | tr '[:upper:]' '[:lower:]')
14if [[ "$os" == "darwin" ]]; then
15 os="mac"
16fi
17arch=$(uname -m)
18
19if [[ "$arch" == "aarch64" ]]; then
20 arch="arm64"
21fi
22
23filename="$APP-$os-$arch.tar.gz"
24
25
26case "$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 ;;
37esac
38
39INSTALL_DIR=$HOME/.opencode/bin
40mkdir -p "$INSTALL_DIR"
41
42if [ -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
50else
51 url="https://github.com/opencode-ai/opencode/releases/download/v${requested_version}/$filename"
52 specific_version=$requested_version
53fi
54
55print_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
69check_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
88download_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
96check_version
97download_and_install
98
99
100add_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
114XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
115
116current_shell=$(basename "$SHELL")
117case $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 ;;
137esac
138
139config_file=""
140for file in $config_files; do
141 if [[ -f $file ]]; then
142 config_file=$file
143 break
144 fi
145done
146
147if [[ -z $config_file ]]; then
148 print_message error "No config file found for $current_shell. Checked files: ${config_files[@]}"
149 exit 1
150fi
151
152if [[ ":$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
174fi
175
176if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then
177 echo "$INSTALL_DIR" >> $GITHUB_PATH
178 print_message info "Added $INSTALL_DIR to \$GITHUB_PATH"
179fi
180