install

  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