Skip to content

Commit 4aecda1

Browse files
hyperpolymathclaude
andcommitted
Add asdf-ephapax-plugin for Ephapax version management
asdf plugin for installing and managing Ephapax versions from GitHub releases. Provides ephapax (compiler), ephapax-lsp (language server), ephapax-dap (debugger), and ephapaxiser (linearity enforcer). Follows the asdf-zig-plugin pattern: - bin/download: fetches release archive from GitHub - bin/install: extracts and verifies binaries - bin/list-all: queries GitHub releases API - bin/latest-stable: gets latest non-prerelease - lib/utils.bash: platform detection, curl with GITHUB_TOKEN Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent bc1b2a7 commit 4aecda1

7 files changed

Lines changed: 275 additions & 0 deletions

File tree

asdf-ephapax-plugin/bin/download

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# Download Ephapax release archive to ASDF_DOWNLOAD_PATH.
4+
5+
set -euo pipefail
6+
7+
current_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
# shellcheck source=../lib/utils.bash
9+
source "${current_script_dir}/../lib/utils.bash"
10+
11+
check_dependencies
12+
13+
if [[ "${ASDF_INSTALL_TYPE:-}" != "version" ]]; then
14+
fail "asdf-ephapax only supports release versions, not refs"
15+
fi
16+
17+
download_path="${ASDF_DOWNLOAD_PATH:?ASDF_DOWNLOAD_PATH is required}"
18+
version="${ASDF_INSTALL_VERSION:?ASDF_INSTALL_VERSION is required}"
19+
20+
mkdir -p "${download_path}"
21+
22+
url="$(get_download_url "${version}")"
23+
archive="${download_path}/ephapax-${version}.tar.gz"
24+
25+
download_file "${url}" "${archive}"
26+
27+
log_info "Extracting to ${download_path}..."
28+
tar -xzf "${archive}" -C "${download_path}" --strip-components=1
29+
30+
rm -f "${archive}"
31+
32+
log_success "Downloaded ephapax ${version}"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
4+
echo "Ephapax — a dyadic language with affine and linear types."
5+
echo ""
6+
echo "Provides: ephapax (compiler), ephapax-lsp (language server),"
7+
echo " ephapax-dap (debugger), ephapaxiser (linearity enforcer)"
8+
echo ""
9+
echo "Homepage: https://github.com/hyperpolymath/ephapax"

asdf-ephapax-plugin/bin/install

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# Install Ephapax from ASDF_DOWNLOAD_PATH to ASDF_INSTALL_PATH.
4+
5+
set -euo pipefail
6+
7+
current_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
# shellcheck source=../lib/utils.bash
9+
source "${current_script_dir}/../lib/utils.bash"
10+
11+
install_path="${ASDF_INSTALL_PATH:?ASDF_INSTALL_PATH is required}"
12+
download_path="${ASDF_DOWNLOAD_PATH:-}"
13+
14+
mkdir -p "${install_path}/bin"
15+
16+
if [[ -z "${download_path}" ]] || [[ ! -d "${download_path}" ]]; then
17+
# No download path — download to temp dir first
18+
tmp_download="${install_path}/tmp_download"
19+
mkdir -p "${tmp_download}"
20+
21+
export ASDF_DOWNLOAD_PATH="${tmp_download}"
22+
"${current_script_dir}/download"
23+
download_path="${tmp_download}"
24+
fi
25+
26+
# Copy downloaded files to install path
27+
cp -r "${download_path}"/* "${install_path}/bin/" 2>/dev/null || true
28+
29+
# Ensure the ephapax binary is executable
30+
if [[ -f "${install_path}/bin/ephapax" ]]; then
31+
chmod +x "${install_path}/bin/ephapax"
32+
elif [[ -f "${install_path}/bin/ephapax-cli" ]]; then
33+
chmod +x "${install_path}/bin/ephapax-cli"
34+
ln -sf "${install_path}/bin/ephapax-cli" "${install_path}/bin/ephapax"
35+
fi
36+
37+
# Also make supporting tools executable if present
38+
for tool in ephapax-lsp ephapax-dap ephapaxiser; do
39+
if [[ -f "${install_path}/bin/${tool}" ]]; then
40+
chmod +x "${install_path}/bin/${tool}"
41+
fi
42+
done
43+
44+
# Clean up tmp download if we created it
45+
if [[ -d "${install_path}/tmp_download" ]]; then
46+
rm -rf "${install_path}/tmp_download"
47+
fi
48+
49+
# Verify installation
50+
if [[ -x "${install_path}/bin/ephapax" ]]; then
51+
local_version=$("${install_path}/bin/ephapax" --version 2>/dev/null || echo "unknown")
52+
log_success "Installed ephapax ${local_version} to ${install_path}"
53+
else
54+
log_warn "ephapax binary not found — release may not include pre-built binaries yet"
55+
log_info "Build from source: cd ${install_path} && just build"
56+
fi
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# Get the latest stable Ephapax version.
4+
5+
set -euo pipefail
6+
7+
current_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
# shellcheck source=../lib/utils.bash
9+
source "${current_script_dir}/../lib/utils.bash"
10+
11+
check_dependencies
12+
get_latest_stable

asdf-ephapax-plugin/bin/list-all

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# List all available Ephapax versions from GitHub releases.
4+
5+
set -euo pipefail
6+
7+
current_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
# shellcheck source=../lib/utils.bash
9+
source "${current_script_dir}/../lib/utils.bash"
10+
11+
check_dependencies
12+
list_all_versions | tr '\n' ' '
13+
echo
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# List binary paths for Ephapax installation.
4+
# Provides: ephapax, ephapax-lsp, ephapax-dap, ephapaxiser
5+
6+
echo "bin"

asdf-ephapax-plugin/lib/utils.bash

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
4+
# asdf-ephapax utility functions
5+
6+
set -euo pipefail
7+
8+
readonly GITHUB_REPO="hyperpolymath/ephapax"
9+
readonly GITHUB_API="https://api.github.com/repos/${GITHUB_REPO}"
10+
11+
export TOOL_NAME="ephapax"
12+
export TOOL_CMD="ephapax"
13+
14+
# Colors for output
15+
if [[ -t 2 ]]; then
16+
readonly RED='\033[0;31m'
17+
readonly GREEN='\033[0;32m'
18+
readonly YELLOW='\033[0;33m'
19+
readonly BLUE='\033[0;34m'
20+
readonly NC='\033[0m'
21+
else
22+
readonly RED=''
23+
readonly GREEN=''
24+
readonly YELLOW=''
25+
readonly BLUE=''
26+
readonly NC=''
27+
fi
28+
29+
log_info() {
30+
echo -e "${BLUE}[asdf-ephapax]${NC} $*" >&2
31+
}
32+
33+
log_success() {
34+
echo -e "${GREEN}[asdf-ephapax]${NC} $*" >&2
35+
}
36+
37+
log_warn() {
38+
echo -e "${YELLOW}[asdf-ephapax]${NC} WARNING: $*" >&2
39+
}
40+
41+
log_error() {
42+
echo -e "${RED}[asdf-ephapax]${NC} ERROR: $*" >&2
43+
}
44+
45+
fail() {
46+
log_error "$*"
47+
exit 1
48+
}
49+
50+
get_platform() {
51+
local os
52+
os="$(uname -s)"
53+
case "${os}" in
54+
Linux*) echo "linux" ;;
55+
Darwin*) echo "macos" ;;
56+
MINGW*|MSYS*|CYGWIN*) echo "windows" ;;
57+
*) fail "Unsupported operating system: ${os}" ;;
58+
esac
59+
}
60+
61+
get_arch() {
62+
local arch
63+
arch="$(uname -m)"
64+
case "${arch}" in
65+
x86_64|amd64) echo "x86_64" ;;
66+
aarch64|arm64) echo "aarch64" ;;
67+
armv7*) echo "armv7a" ;;
68+
i686|i386) echo "x86" ;;
69+
*) fail "Unsupported architecture: ${arch}" ;;
70+
esac
71+
}
72+
73+
curl_wrapper() {
74+
local -a curl_args=("-fsSL" "--retry" "3" "--retry-delay" "2")
75+
76+
# Use GITHUB_TOKEN if available for higher rate limits
77+
if [[ -n "${GITHUB_TOKEN:-}" ]] || [[ -n "${GITHUB_API_TOKEN:-}" ]]; then
78+
local token="${GITHUB_TOKEN:-${GITHUB_API_TOKEN}}"
79+
curl_args+=("-H" "Authorization: token ${token}")
80+
fi
81+
82+
curl "${curl_args[@]}" "$@"
83+
}
84+
85+
download_file() {
86+
local url="$1"
87+
local output="$2"
88+
89+
log_info "Downloading ${url}..."
90+
91+
if ! curl_wrapper -o "${output}" "${url}"; then
92+
fail "Failed to download: ${url}"
93+
fi
94+
}
95+
96+
list_all_versions() {
97+
# Query GitHub releases API for all Ephapax versions
98+
local releases
99+
releases=$(curl_wrapper "${GITHUB_API}/releases" 2>/dev/null || echo "[]")
100+
101+
echo "${releases}" \
102+
| grep '"tag_name"' \
103+
| sed 's/.*"tag_name": *"v\{0,1\}\([^"]*\)".*/\1/' \
104+
| sort -V
105+
}
106+
107+
get_latest_stable() {
108+
# Get the latest non-prerelease version
109+
local releases
110+
releases=$(curl_wrapper "${GITHUB_API}/releases/latest" 2>/dev/null || echo "{}")
111+
112+
echo "${releases}" \
113+
| grep '"tag_name"' \
114+
| head -1 \
115+
| sed 's/.*"tag_name": *"v\{0,1\}\([^"]*\)".*/\1/'
116+
}
117+
118+
get_download_url() {
119+
local version="$1"
120+
local platform
121+
local arch
122+
platform="$(get_platform)"
123+
arch="$(get_arch)"
124+
125+
# Ephapax release artifact naming convention:
126+
# ephapax-{version}-{platform}-{arch}.tar.gz
127+
echo "https://github.com/${GITHUB_REPO}/releases/download/v${version}/ephapax-${version}-${platform}-${arch}.tar.gz"
128+
}
129+
130+
command_exists() {
131+
command -v "$1" >/dev/null 2>&1
132+
}
133+
134+
check_dependencies() {
135+
local -a required=(curl tar grep sed sort cut mkdir rm)
136+
local missing=()
137+
138+
for cmd in "${required[@]}"; do
139+
if ! command_exists "${cmd}"; then
140+
missing+=("${cmd}")
141+
fi
142+
done
143+
144+
if [[ ${#missing[@]} -gt 0 ]]; then
145+
fail "Missing required dependencies: ${missing[*]}"
146+
fi
147+
}

0 commit comments

Comments
 (0)