Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 57 additions & 35 deletions bin/install
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
#!/usr/bin/env bash

set -e
set -o pipefail
set -euo pipefail

ASDF_INSTALL_TYPE=${ASDF_INSTALL_TYPE:-version }
ASDF_INSTALL_TYPE=${ASDF_INSTALL_TYPE:-version}
TMPDIR=${TMPDIR:-/tmp}
[ -n "$ASDF_INSTALL_VERSION" ] || (>&2 echo 'Missing ASDF_INSTALL_VERSION' && exit 1)
[ -n "$ASDF_INSTALL_PATH" ] || (>&2 echo 'Missing ASDF_INSTALL_PATH' && exit 1)
[ -n "${ASDF_INSTALL_VERSION:-}" ] || { echo 'Missing ASDF_INSTALL_VERSION' >&2; exit 1; }
[ -n "${ASDF_INSTALL_PATH:-}" ] || { echo 'Missing ASDF_INSTALL_PATH' >&2; exit 1; }

# Compare two semantic versions using portable sort
# Returns 0 if version1 >= version2, 1 otherwise
version_gte() {
local version1=$1
local version2=$2
local version1="$1"
local version2="$2"
# Use portable version sorting (same logic as sort_versions in list-all)
local sorted_first
sorted_first=$(printf '%s\n%s\n' "$version1" "$version2" | \
Expand All @@ -22,49 +21,32 @@ version_gte() {
[ "$sorted_first" = "$version2" ]
}

install_opencode() {
local version=$2
local install_path=$3
local bin_install_path="$install_path/bin"
local download_url="$(get_download_url $version)"

mkdir -p "${install_path}"
mkdir -p "${bin_install_path}"
local bin_path="${bin_install_path}/opencode"
echo "downloading opencode ${download_url}"
if [[ "$download_url" == *.tar.gz ]]; then
curl -sL "$download_url" | tar -xz -C "${install_path}"
else
curl -L -s "$download_url" | funzip > "${install_path}/opencode"
fi
mv "${install_path}/opencode" "${bin_install_path}/opencode"
chmod +x "$bin_path"
}

get_platform() {
local platform=$(uname | tr 'A-Z' 'a-z')
echo $platform
uname | tr '[:upper:]' '[:lower:]'
}

get_arch() {
local arch=$(uname -m)
case $arch in
local arch
arch=$(uname -m)
case "$arch" in
x86_64|amd64)
echo "x64"
;;
*)
echo $arch
echo "$arch"
;;
esac
}


get_download_url() {
local version="$1"
local platform="$(get_platform)"
local arch="$(get_arch)"
local platform
local arch
local ext="zip"

platform="$(get_platform)"
arch="$(get_arch)"

# Linux switched from .zip to .tar.gz starting with v1.0.92
if [ "$platform" = "linux" ]; then
if version_gte "$version" "1.0.92"; then
Expand All @@ -75,4 +57,44 @@ get_download_url() {
echo "https://github.com/sst/opencode/releases/download/v${version}/opencode-${platform}-${arch}.${ext}"
}

install_opencode $ASDF_INSTALL_TYPE $ASDF_INSTALL_VERSION $ASDF_INSTALL_PATH
install_opencode() {
local install_type="$1"
local version="$2"
local install_path="$3"
local bin_install_path="${install_path}/bin"
local download_url

download_url="$(get_download_url "$version")"

# Create a secure temporary directory for download
# Use global variable so trap can access it
TMP_DOWNLOAD_DIR=$(mktemp -d "${TMPDIR}/asdf-opencode.XXXXXX")
trap 'rm -rf "${TMP_DOWNLOAD_DIR:-}"' EXIT

mkdir -p "$install_path"
mkdir -p "$bin_install_path"

local bin_path="${bin_install_path}/opencode"

echo "Downloading opencode from ${download_url}"

# Note: Upstream does not publish checksums, so verification is not possible.
# Using --fail to error on HTTP failures instead of downloading error pages.
if [[ "$download_url" == *.tar.gz ]]; then
curl -fSL "$download_url" -o "${TMP_DOWNLOAD_DIR}/opencode.tar.gz"
tar -xzf "${TMP_DOWNLOAD_DIR}/opencode.tar.gz" -C "$TMP_DOWNLOAD_DIR"
else
curl -fSL "$download_url" -o "${TMP_DOWNLOAD_DIR}/opencode.zip"
funzip "${TMP_DOWNLOAD_DIR}/opencode.zip" > "${TMP_DOWNLOAD_DIR}/opencode"
fi

mv "${TMP_DOWNLOAD_DIR}/opencode" "$bin_path"
chmod +x "$bin_path"

rm -rf "$TMP_DOWNLOAD_DIR"
trap - EXIT

echo "opencode ${version} installed to ${bin_path}"
}

install_opencode "$ASDF_INSTALL_TYPE" "$ASDF_INSTALL_VERSION" "$ASDF_INSTALL_PATH"
50 changes: 31 additions & 19 deletions bin/list-all
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
#!/usr/bin/env bash

releases_path=https://api.github.com/repos/sst/opencode/releases
set -euo pipefail

cmd_prefix="curl --verbose --retry 10 --retry-delay 2 -s"
if [ -n "$GITHUB_API_TOKEN" ]; then
cmd_prefix="$cmd_prefix -H 'Authorization: token $GITHUB_API_TOKEN'"
releases_path="https://api.github.com/repos/sst/opencode/releases"

# Build curl arguments as an array to avoid eval
curl_args=(--retry 10 --retry-delay 2 -sfS)
if [ -n "${GITHUB_API_TOKEN:-}" ]; then
curl_args+=(-H "Authorization: token $GITHUB_API_TOKEN")
fi

next_link="${releases_path}?per_page=100&page=1"
all_versions=""

while [ -n "${next_link}" ]; do

# Download releases page
cmd="${cmd_prefix} \"${next_link}\""
cmd_out=$(eval "${cmd}" 2>&1)

# Get versions
versions=$(echo "${cmd_out}" | grep tag_name | cut -d'"' -f4 | sed 's/^v//')
all_versions="${versions}\n${all_versions}"

# Get next link
next_link=$(echo "${cmd_out}" | grep '< link: ' | sed 's/< link: <\(.*\)>; rel="next".*$/\1/')
next_link=$(echo "${next_link}" | sed 's/^.*<\(.*\)$/\1/')

# Download releases page, capture headers separately
header_file=$(mktemp)
trap "rm -f '$header_file'" EXIT

response=$(curl "${curl_args[@]}" -D "$header_file" "$next_link") || {
rm -f "$header_file"
exit 1
}

# Get versions from response
versions=$(echo "$response" | grep '"tag_name"' | cut -d'"' -f4 | sed 's/^v//')
all_versions="${versions}"$'\n'"${all_versions}"

# Get next link from headers (safely parse Link header)
next_link=""
if grep -qi '^link:' "$header_file"; then
# Extract URL marked as rel="next"
next_link=$(grep -i '^link:' "$header_file" | sed -n 's/.*<\([^>]*\)>; rel="next".*/\1/p')
fi

rm -f "$header_file"
trap - EXIT
done

# stolen from https://github.com/rbenv/ruby-build/pull/631/files#diff-fdcfb8a18714b33b07529b7d02b54f1dR942
function sort_versions() {
sort_versions() {
sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z\1/; s/$/.z/; G; s/\n/ /' | \
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
}

echo -e "${all_versions}" | sort_versions | tr '\n' ' ' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
echo "$all_versions" | sort_versions | tr '\n' ' ' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'