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
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,5 @@ jobs:
files: |
vyn-*
scripts/install.sh
scripts/uninstall.sh
generate_release_notes: true
21 changes: 21 additions & 0 deletions Dockerfile.cli
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# syntax=docker/dockerfile:1
# Builds the vyn CLI binary inside Docker and copies it to /output.
# Usage:
# docker build -f Dockerfile.cli -t vyn-cli-builder .
# docker run --rm -v "$HOME/.local/bin:/output" vyn-cli-builder
# The binary will be placed at $HOME/.local/bin/vyn (ensure that dir is in PATH).

FROM rust:1-alpine AS builder
RUN apk add --no-cache musl-dev pkgconf openssl-dev openssl-libs-static

WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY crates ./crates
COPY proto ./proto

RUN cargo build --release --bin vyn

FROM alpine:3 AS export
COPY --from=builder /app/target/release/vyn /vyn

ENTRYPOINT ["/bin/sh", "-c", "cp /vyn /output/vyn && echo 'vyn installed to /output/vyn' && /output/vyn --version"]
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- [Option A: Install from crates.io (recommended)](#option-a-install-from-cratesio-recommended)
- [Option B: Pre-built binary](#option-b-pre-built-binary)
- [Option C: Build from source](#option-c-build-from-source)
- [Uninstall](#uninstall)
- [Quick Start](#quick-start)
- [Configuration](#configuration)
- [Relay Deployment](#relay-deployment)
Expand Down Expand Up @@ -82,13 +83,54 @@ Download `vyn-x86_64-pc-windows-msvc.zip` from [releases](https://github.com/arn

### Option C: Build from source

**With Rust toolchain**

```bash
git clone https://github.com/arnonsang/vyn.git
cd vyn
cargo install --path crates/vyn-cli
vyn --help
```

**Via Docker**

Compiles from source inside Docker and copies the binary to your host.

```bash
git clone https://github.com/arnonsang/vyn.git
cd vyn
docker build -f Dockerfile.cli -t vyn-cli-builder .
docker run --rm -v "$HOME/.local/bin:/output" vyn-cli-builder
```

Make sure `~/.local/bin` is in your `PATH`, then verify:

```bash
vyn --help
```

To update, re-pull and rebuild:

```bash
git -C vyn pull
docker build -f Dockerfile.cli -t vyn-cli-builder .
docker run --rm -v "$HOME/.local/bin:/output" vyn-cli-builder
```

### Uninstall

Detects how `vyn` was installed and removes the binary and global config.

```bash
curl -fsSL https://github.com/arnonsang/vyn/releases/latest/download/uninstall.sh | sh
```

or with wget:

```bash
wget -qO- https://github.com/arnonsang/vyn/releases/latest/download/uninstall.sh | sh
```

## Quick Start

```bash
Expand Down
2 changes: 1 addition & 1 deletion crates/vyn-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ fn detect_and_store_install_method() {
let exe_str = exe.to_string_lossy().to_lowercase();
if exe_str.contains(".cargo/bin") || exe_str.contains(".cargo\\bin") {
Some("cargo".to_string())
} else if exe_str.contains("/usr/local/bin") {
} else if exe_str.contains("/usr/local/bin") || exe_str.contains("/.local/bin") {
Some("binary".to_string())
} else {
None
Expand Down
76 changes: 76 additions & 0 deletions scripts/uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env sh
set -e

BIN="vyn"
VYN_GLOBAL_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/vyn"
GLOBAL_TOML="$VYN_GLOBAL_DIR/global.toml"

# Read install_method from global.toml if present
install_method=""
if [ -f "$GLOBAL_TOML" ]; then
install_method="$(grep '^install_method' "$GLOBAL_TOML" | sed 's/.*= *"\(.*\)"/\1/')"
fi

# Fall back to detecting from binary path
if [ -z "$install_method" ]; then
BIN_PATH="$(command -v "$BIN" 2>/dev/null || true)"
if [ -n "$BIN_PATH" ]; then
case "$BIN_PATH" in
*/.cargo/bin/*) install_method="cargo" ;;
*/.local/bin/*|*/usr/local/bin/*) install_method="binary" ;;
esac
fi
fi

echo "Detected install method: ${install_method:-unknown}"

remove_binary() {
target="$1"
if [ -f "$target" ]; then
if [ -w "$target" ]; then
rm "$target"
else
sudo rm "$target"
fi
echo "Removed $target"
else
echo "Binary not found at $target, skipping."
fi
}

case "$install_method" in
binary)
# Try common binary install paths
for dir in "/usr/local/bin" "$HOME/.local/bin"; do
if [ -f "$dir/$BIN" ]; then
remove_binary "$dir/$BIN"
break
fi
done
;;
cargo)
if command -v cargo >/dev/null 2>&1; then
cargo uninstall vyn-cli
else
# cargo not on PATH, find and remove manually
remove_binary "$HOME/.cargo/bin/$BIN"
fi
;;
*)
# Unknown method: find the binary wherever it is
BIN_PATH="$(command -v "$BIN" 2>/dev/null || true)"
if [ -n "$BIN_PATH" ]; then
remove_binary "$BIN_PATH"
else
echo "Could not locate $BIN binary. Remove it manually."
fi
;;
esac

# Remove global config
if [ -d "$VYN_GLOBAL_DIR" ]; then
rm -rf "$VYN_GLOBAL_DIR"
echo "Removed $VYN_GLOBAL_DIR"
fi

echo "vyn uninstalled."
Loading