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
6 changes: 5 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
target: x86_64-unknown-linux-musl
artifact_name: uvup
asset_name: uvup-linux-x86_64
- os: macos-latest
Expand All @@ -36,6 +36,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Install musl tools (Linux)
if: matrix.target == 'x86_64-unknown-linux-musl'
run: sudo apt-get update && sudo apt-get install -y musl-tools

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
Expand Down
108 changes: 98 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,86 @@ uvup aims to be a companion tool for uv, providing a familiar conda-like interfa

## Installation

### For Users
### Quick Install (Recommended)

Coming soon - prebuilt binaries will be available on GitHub Releases.
**Linux and macOS:**
```bash
curl -fsSL https://raw.githubusercontent.com/KercyDing/uvup/main/scripts/install.sh | sh
```

**Windows (PowerShell):**
```powershell
Invoke-RestMethod https://raw.githubusercontent.com/KercyDing/uvup/main/scripts/install.ps1 | Invoke-Expression
```

The installation script will automatically configure shell integration for you. Restart your terminal or run:

```bash
# Linux/macOS
source ~/.zshrc # or ~/.bashrc for bash

# Windows (PowerShell)
. $PROFILE
```

### Manual Installation

Download the latest release for your platform from [GitHub Releases](https://github.com/KercyDing/uvup/releases):

**Linux:**
```bash
# Download and install
wget https://github.com/KercyDing/uvup/releases/latest/download/uvup-linux-x86_64
chmod +x uvup-linux-x86_64
sudo mv uvup-linux-x86_64 /usr/local/bin/uvup

# Initialize shell integration
echo 'eval "$(uvup init)"' >> ~/.bashrc # or ~/.zshrc for zsh
source ~/.bashrc
```

**macOS:**
```bash
# Download and install (Apple Silicon)
wget https://github.com/KercyDing/uvup/releases/latest/download/uvup-macos-arm64
chmod +x uvup-macos-arm64
sudo mv uvup-macos-arm64 /usr/local/bin/uvup

# OR for Intel Macs
wget https://github.com/KercyDing/uvup/releases/latest/download/uvup-macos-x86_64
chmod +x uvup-macos-x86_64
sudo mv uvup-macos-x86_64 /usr/local/bin/uvup

# Initialize shell integration
echo 'eval "$(uvup init)"' >> ~/.zshrc
source ~/.zshrc
```

**Windows:**

1. Download [uvup-windows-x86_64.exe](https://github.com/KercyDing/uvup/releases/latest/download/uvup-windows-x86_64.exe)

2. Create directory and move the binary:
```powershell
New-Item -ItemType Directory -Force -Path "$env:LOCALAPPDATA\Programs\uvup"
Move-Item uvup-windows-x86_64.exe "$env:LOCALAPPDATA\Programs\uvup\uvup.exe"
```

3. Add to PATH:
- Press `Win + R`, type `sysdm.cpl`, press Enter
- Go to "Advanced" tab → "Environment Variables"
- Under "User variables", select "Path" and click "Edit"
- Click "New" and add: `%LOCALAPPDATA%\Programs\uvup`
- Click OK to save

4. Initialize shell integration (restart terminal first):
```powershell
# Add to profile for all PowerShell hosts
Add-Content -Path $PROFILE.CurrentUserAllHosts -Value "`nInvoke-Expression ((uvup init) -join `"``n`")"

# Load in current session
Invoke-Expression ((uvup init) -join "`n")
```

### For Developers

Expand All @@ -33,12 +110,23 @@ cargo install --path .
```

3. Initialize shell integration:

**Linux/macOS:**
```bash
# Add to your shell configuration
echo 'eval "$(uvup init)"' >> ~/.zshrc # or ~/.bashrc for bash
source ~/.zshrc
```

**Windows (PowerShell):**
```powershell
# Add to profile for all PowerShell hosts
Add-Content -Path $PROFILE.CurrentUserAllHosts -Value "`nInvoke-Expression ((uvup init) -join `"``n`")"

# Load in current session
Invoke-Expression ((uvup init) -join "`n")
```

#### Development Workflow

During development, you have several options:
Expand All @@ -64,20 +152,20 @@ cargo build

## Planned Features

### MVP (v0.1.0) - Completed
### MVP (v0.1.0) - Completed

- `uvup init` - Shell integration
- `uvup create <name>` - Create environments
- `uvup activate <name>` - Activate environments (via shell hook)
- `uvup list` - List all environments
- `uvup remove <name>` - Remove environments
- [x] `uvup init` - Shell integration (Bash, Zsh, Fish, PowerShell)
- [x] `uvup create <name>` - Create environments
- [x] `uvup activate <name>` - Activate environments (via shell hook)
- [x] `uvup list` - List all environments
- [x] `uvup remove <name>` - Remove environments

### Future Versions

- `uvup default <name>` - Set default environment (auto-activate on new terminal)
- `uvup undefault` - Remove default environment
- Enhanced shell support (Fish, PowerShell)
- Cross-platform distribution (Homebrew, Scoop, Winget)
- Installation via package managers (Homebrew, Scoop, Winget)
- Enhanced `list` command with more environment details

## Usage

Expand Down
82 changes: 82 additions & 0 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Check execution policy
$executionPolicy = Get-ExecutionPolicy -Scope CurrentUser
if ($executionPolicy -eq "Restricted" -or $executionPolicy -eq "Undefined") {
Write-Host "Error: PowerShell script execution is disabled on this system." -ForegroundColor Red
Write-Host ""
Write-Host "To allow script execution, run the following command:" -ForegroundColor Yellow
Write-Host " Set-ExecutionPolicy RemoteSigned -Scope CurrentUser" -ForegroundColor White
Write-Host ""
Write-Host "Then run this installation script again." -ForegroundColor Yellow
exit 1
}

$ErrorActionPreference = "Stop"

Write-Host "Downloading uvup for Windows..." -ForegroundColor Green

$DOWNLOAD_URL = "https://github.com/KercyDing/uvup/releases/latest/download/uvup-windows-x86_64.exe"
$INSTALL_DIR = "$env:LOCALAPPDATA\Programs\uvup"
$INSTALL_PATH = "$INSTALL_DIR\uvup.exe"

# Create install directory
New-Item -ItemType Directory -Force -Path $INSTALL_DIR | Out-Null

# Download binary
try {
Invoke-WebRequest -Uri $DOWNLOAD_URL -OutFile $INSTALL_PATH -UseBasicParsing
} catch {
Write-Host "Error: Failed to download uvup" -ForegroundColor Red
exit 1
}

Write-Host "uvup installed to $INSTALL_PATH" -ForegroundColor Green

# Add to PATH if not already present
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($userPath -notlike "*$INSTALL_DIR*") {
Write-Host "Adding $INSTALL_DIR to PATH..." -ForegroundColor Yellow
[Environment]::SetEnvironmentVariable("Path", "$userPath;$INSTALL_DIR", "User")
$env:Path = "$env:Path;$INSTALL_DIR"
Write-Host "PATH updated. You may need to restart your terminal." -ForegroundColor Yellow
}

Write-Host ""
Write-Host "uvup installed successfully!" -ForegroundColor Green

# Add uvup initialization to PowerShell profile
# Use CurrentUserAllHosts (profile.ps1) - works for all PowerShell hosts
$PROFILE_PATH = $PROFILE.CurrentUserAllHosts
if (-not $PROFILE_PATH) {
$PROFILE_PATH = "$env:USERPROFILE\Documents\PowerShell\profile.ps1"
}

Write-Host ""
Write-Host "Configuring PowerShell profile..." -ForegroundColor Cyan

# Create profile if it doesn't exist
if (-not (Test-Path $PROFILE_PATH)) {
$profileDir = Split-Path $PROFILE_PATH -Parent
if (-not (Test-Path $profileDir)) {
New-Item -ItemType Directory -Path $profileDir -Force | Out-Null
}
New-Item -ItemType File -Path $PROFILE_PATH -Force | Out-Null
Write-Host "Created profile at: $PROFILE_PATH" -ForegroundColor Green
}

# Check if already exists
$profileContent = Get-Content $PROFILE_PATH -Raw -ErrorAction SilentlyContinue
if ($profileContent -match 'uvup init.*Invoke-Expression') {
Write-Host "uvup initialization already exists in profile" -ForegroundColor Yellow
} else {
# Add initialization line
$initLine = 'Invoke-Expression ((uvup init) -join "`n")'
Add-Content -Path $PROFILE_PATH -Value "`n# uvup initialization"
Add-Content -Path $PROFILE_PATH -Value $initLine
Write-Host "Added uvup initialization to profile" -ForegroundColor Green
}

Write-Host ""
Write-Host "To start using uvup, run:" -ForegroundColor Cyan
Write-Host " . `$PROFILE" -ForegroundColor White
Write-Host ""
Write-Host "Or restart your terminal." -ForegroundColor Cyan
132 changes: 132 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/bin/sh
set -e

# uvup installer script

# Detect OS and architecture
OS="$(uname -s)"
ARCH="$(uname -m)"

# Determine download URL
case "$OS" in
Linux*)
if [ "$ARCH" = "x86_64" ]; then
BINARY="uvup-linux-x86_64"
else
echo "Error: Unsupported architecture $ARCH for Linux"
exit 1
fi
;;
Darwin*)
if [ "$ARCH" = "arm64" ]; then
BINARY="uvup-macos-arm64"
elif [ "$ARCH" = "x86_64" ]; then
BINARY="uvup-macos-x86_64"
else
echo "Error: Unsupported architecture $ARCH for macOS"
exit 1
fi
;;
*)
echo "Error: Unsupported operating system $OS"
exit 1
;;
esac

DOWNLOAD_URL="https://github.com/KercyDing/uvup/releases/latest/download/$BINARY"

echo "Downloading uvup for $OS $ARCH..."
TEMP_FILE=$(mktemp)
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$DOWNLOAD_URL" -o "$TEMP_FILE"
elif command -v wget >/dev/null 2>&1; then
wget -q "$DOWNLOAD_URL" -O "$TEMP_FILE"
else
echo "Error: curl or wget is required"
exit 1
fi

# Make executable
chmod +x "$TEMP_FILE"

# Determine install directory
if [ -w "/usr/local/bin" ]; then
INSTALL_DIR="/usr/local/bin"
sudo=""
elif [ "$(id -u)" -eq 0 ]; then
INSTALL_DIR="/usr/local/bin"
sudo=""
else
INSTALL_DIR="$HOME/.local/bin"
sudo=""
mkdir -p "$INSTALL_DIR"
fi

# Move to install directory
echo "Installing uvup to $INSTALL_DIR..."
if [ -n "$sudo" ]; then
$sudo mv "$TEMP_FILE" "$INSTALL_DIR/uvup"
else
mv "$TEMP_FILE" "$INSTALL_DIR/uvup"
fi

echo "uvup installed successfully!"

# Check if install directory is in PATH
case ":$PATH:" in
*":$INSTALL_DIR:"*) ;;
*)
echo ""
echo "Warning: $INSTALL_DIR is not in your PATH"
echo "Add the following to your shell configuration file:"
echo " export PATH=\"$INSTALL_DIR:\$PATH\""
;;
esac

# Detect shell and provide init instructions
SHELL_NAME=$(basename "$SHELL")
SHELL_RC=""
INIT_LINE=""

case "$SHELL_NAME" in
bash)
SHELL_RC="$HOME/.bashrc"
INIT_LINE='eval "$(uvup init)"'
;;
zsh)
SHELL_RC="$HOME/.zshrc"
INIT_LINE='eval "$(uvup init)"'
;;
fish)
SHELL_RC="$HOME/.config/fish/config.fish"
INIT_LINE='uvup init | source'
;;
*)
SHELL_RC="$HOME/.profile"
INIT_LINE='eval "$(uvup init)"'
;;
esac

echo ""
echo "Configuring shell integration..."

# Check if already exists
if [ -f "$SHELL_RC" ] && grep -q "eval.*uvup init\|uvup init.*source" "$SHELL_RC"; then
echo "uvup initialization already exists in $SHELL_RC"
else
# Create shell RC if it doesn't exist
touch "$SHELL_RC"

# Add init line
echo "" >> "$SHELL_RC"
echo "# uvup initialization" >> "$SHELL_RC"
echo "$INIT_LINE" >> "$SHELL_RC"

echo "Added uvup initialization to $SHELL_RC"
fi

echo ""
echo "To start using uvup, run:"
echo " source $SHELL_RC"
echo ""
echo "Or restart your terminal."
Loading