Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Soar

Fast, modern, bloat-free package manager for Linux

Install static binaries, AppImages, and portable packages across any distro — no root required.

curl -fsSL https://soar.qaidvoid.dev/install.sh | sh

Then add to your PATH and install your first package:

echo 'export PATH="$HOME/.local/share/soar/bin:$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
soar install neovim

Why Soar?

Universal Packages

Static binaries, AppImages, FlatImages — one tool handles them all. Packages come from bincache and pkgcache repositories.

Fast & Efficient

Written in Rust. Pre-built binary cache means no local compilation. Parallel downloads and installs keep things moving.

Distro-Independent

Works the same on Debian, Arch, Fedora, Alpine, or anything else running Linux. No system dependencies.

Secure by Design

Packages built on remote CI servers with auditable build logs. Verified with BLAKE3 checksums and minisign signatures.

Desktop Integration

Follows freedesktop.org specs — automatic desktop entries, icon scaling, and menu integration.

No Root Needed

Everything installs to your home directory by default. No sudo, no system-level changes, fully portable.


Quick Navigation

Quick Start Guide

Get started with Soar in under 5 minutes.

First Time Setup

Step 1: Install Soar

curl -fsSL https://soar.qaidvoid.dev/install.sh | sh

Step 2: Verify Installation

soar --version

Step 3: Add to PATH

echo 'export PATH="$HOME/.local/share/soar/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Step 4: Install Your First Package

soar sync
soar install neovim

Need more options? See Installation Guide


Daily Package Management

Search Packages

soar search python
soar query neovim

Install Packages

soar install git
soar install git curl wget
soar install https://example.com/package.AppImage

List Packages

soar list
soar info

Update Packages

soar update
soar update neovim git

Remove Packages

soar remove neovim

Run Without Installing

soar run neovim

Switching from Another Package Manager

From apt (Debian/Ubuntu)

Taskapt CommandSoar Equivalent
Update cachesudo apt updatesoar sync
Installsudo apt install <pkg>soar install <pkg>
Removesudo apt remove <pkg>soar remove <pkg>
Updatesudo apt upgradesoar update
Searchapt search <query>soar search <query>
List installedapt list --installedsoar info

From pacman (Arch Linux)

Taskpacman CommandSoar Equivalent
Update databasesudo pacman -Sysoar sync
Installsudo pacman -S <pkg>soar install <pkg>
Removesudo pacman -R <pkg>soar remove <pkg>
Update systemsudo pacman -Syusoar update
Searchpacman -Ss <query>soar search <query>
List installedpacman -Qesoar info

Managing Multiple Systems

Profiles let you maintain separate package environments.

Create a Profile

Edit ~/.config/soar/config.toml:

[profile.default]
root_path = "~/.local/share/soar"

[profile.dev]
root_path = "~/dev-tools"

Use Profiles

soar --profile dev install neovim
soar --profile dev list
soar --profile dev update

Set Default Profile

default_profile = "dev"

Troubleshooting

Having issues? Run diagnostics:

soar health

For comprehensive troubleshooting, see Health & Diagnostics.


What’s Next?

Installation

Install Soar on your Linux system using one of the following methods.

Prerequisites: Linux (any distribution), curl or wget, basic shell access.

System Requirements

  • Architectures: x86_64, aarch64, riscv64
  • OS: Any Linux distribution (kernel 4.0+ recommended)
  • Building from source: Rust 1.88.0+

Quick Installation

curl -fsSL https://soar.qaidvoid.dev/install.sh | sh

Or with wget:

wget -qO- https://soar.qaidvoid.dev/install.sh | sh

The script automatically detects your architecture, downloads the appropriate binary, and installs it to:

  • /usr/local/bin (if running as root)
  • $HOME/.local/bin (user installation, default)

Install Script Options

VariablePurposeExample
SOAR_VERSIONSpecify versionlatest, nightly, 0.4.0
SOAR_INSTALL_DIRCustom directory/usr/local/bin, $HOME/.local/bin
DEBUGEnable debug outputSet to any value

Examples:

# Install specific version
curl -fsSL https://soar.qaidvoid.dev/install.sh | SOAR_VERSION=0.4.0 sh

# Install to custom directory
curl -fsSL https://soar.qaidvoid.dev/install.sh | SOAR_INSTALL_DIR=$HOME/.local/bin sh

# Enable debug output
curl -fsSL https://soar.qaidvoid.dev/install.sh | DEBUG=1 sh

Manual Installation

From Pre-built Binaries

  1. Download from releases

  2. Choose your architecture:

    • soar-x86_64-linux (Intel/AMD)
    • soar-aarch64-linux (ARM 64-bit)
    • soar-riscv64-linux (RISC-V 64-bit)
  3. Install:

chmod +x soar-x86_64-linux
sudo mv soar-x86_64-linux /usr/local/bin/soar

From Cargo

cargo install soar-cli

Requires Rust toolchain. Takes longer due to compilation.

Building from Source

git clone https://github.com/pkgforge/soar.git
cd soar
cargo install --path .

Requires Rust 1.88.0+.

PATH Configuration

Two directories should be in your PATH:

  • $HOME/.local/bin — where the soar binary is installed
  • $HOME/.local/share/soar/bin — where packages installed by Soar are symlinked
# Add both to PATH (Bash/Zsh)
echo 'export PATH="$HOME/.local/share/soar/bin:$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Uninstallation

Remove Soar

# User installation
rm ~/.local/bin/soar
rm -rf ~/.config/soar ~/.local/share/soar

# System installation
sudo rm /usr/local/bin/soar
sudo rm -rf /etc/soar /opt/soar

Or use the self-uninstall command:

soar self uninstall

Remove Packages

soar remove ffmpeg
soar remove --all

Troubleshooting

“Command not found” after installation:

  1. Verify binary exists: ls -la ~/.local/bin/soar
  2. Check PATH: echo $PATH
  3. Add to PATH (see PATH Configuration)
  4. Restart shell: source ~/.bashrc

“Permission denied” installing:

  • Use user installation: SOAR_INSTALL_DIR=$HOME/.local/bin
  • Or use sudo: sudo curl -fsSL https://soar.qaidvoid.dev/install.sh | sh

Download fails:

  • Try alternative CDN: curl -fsSL https://soar.pkgforge.dev/install.sh | sh
  • Use wget: wget -qO- https://soar.qaidvoid.dev/install.sh | sh
  • Download manually from GitHub releases

Build from source fails:

  • Check Rust version: rustc --version (requires 1.88.0+)
  • Update Rust: rustup update
  • Install dependencies: sudo apt install build-essential pkg-config libssl-dev

For more help, run soar health check verbose output with --verbose, or visit GitHub Issues.

Next Steps

# Verify installation
soar --version

# Sync repositories
soar sync

# Install your first package
soar install ffmpeg

Configuration

Soar stores configuration at ~/.config/soar/config.toml. If the file doesn’t exist, sensible defaults are used.

Quick Start: Run soar defconfig to create a default configuration file.

Configuration Reference

Configuration OptionTypeDefaultDescription
Path Settings
cache_pathString~/.local/share/soar/cacheDirectory for cached package files
db_pathString~/.local/share/soar/dbPath to package database
bin_pathString~/.local/share/soar/binDirectory for binary symlinks
repositories_pathString~/.local/share/soar/reposLocal repository clones
portable_dirsString~/.local/share/soar/portable-dirsBase path for portable app data (AppImage/FlatImage/RunImage/Wrappe only)
Performance
parallelBooleantrueEnable parallel downloads
parallel_limitInteger4Max parallel downloads (1-16)
ghcr_concurrencyInteger8Max GHCR concurrent requests (1-32)
search_limitInteger20Max search results (5-100)
cross_repo_updatesBooleanfalseAllow cross-repo updates (not implemented)
Package Installation
install_patternsArray["!*.log", "!SBUILD", "!*.json", "!*.version"]Files to exclude during installation
Security
signature_verificationBooleannull (auto)Enable package signature verification
Desktop Integration
desktop_integrationBooleannull (repo-specific)Enable desktop menu entries
Repository Sync
sync_intervalString"3h"How often to sync repositories
Display Settings
display.progress_styleString"modern"Progress bar style: classic, modern, minimal
display.iconsBooleantrueShow Unicode icons
display.spinnersBooleantrueShow animated spinners

Special sync_interval values: "always", "never", "auto" (3h), or duration like "30m", "6h", "1d"

Key Options

Path Settings

Control where Soar stores data. Add bin_path to your PATH:

export PATH="$HOME/.local/share/soar/bin:$PATH"

Performance

  • parallel / parallel_limit: Increase for faster downloads on stable connections, decrease for slow/unstable connections
  • ghcr_concurrency: Adjust if experiencing GHCR rate limiting

Install Patterns

Glob patterns for files to exclude during installation. Patterns starting with ! are exclusions:

install_patterns = [
    "!*.log",      # Exclude log files
    "!SBUILD",     # Exclude build scripts
    "!*.debug",    # Exclude debug symbols
]

Security

signature_verification: Set to true for maximum security, false for trusted local repos. Can be overridden per-repository.

Desktop Integration

desktop_integration: Enable for GUI applications to appear in application menus. Can be set globally or per-repository.

Display Settings

[display]
progress_style = "modern"  # classic, modern, minimal
icons = true
spinners = true

Repositories

Repositories are defined as arrays of tables in your configuration:

[[repositories]]
name = "bincache"
url = "https://meta.pkgforge.dev/bincache/x86_64-Linux.sdb.zstd"
pubkey = "https://meta.pkgforge.dev/bincache/minisign.pub"
desktop_integration = false
enabled = true
signature_verification = true
sync_interval = "3h"

Repository Fields

FieldTypeDefaultDescription
nameString(required)Unique repository name. Note: "local" is reserved
urlString(required)URL to repository metadata
pubkeyStringnullURL to repository’s public key
enabledBooleantrueEnable/disable this repository
desktop_integrationBooleanfalseEnable desktop integration for packages
signature_verificationBooleanautoEnable signature verification (auto-enabled if pubkey exists)
sync_intervalString"3h"Sync interval: "always", "never", "auto", or duration

Default Repositories

Soar includes these default repositories for Linux platforms (aarch64, riscv64, x86_64):

  • bincache: Stripped binaries with no desktop integration

    • URL: https://meta.pkgforge.dev/bincache/{platform}.sdb.zstd
    • Signature verification enabled
    • Desktop integration disabled
  • pkgcache: Full packages with desktop integration

    • URL: https://meta.pkgforge.dev/pkgcache/{platform}.sdb.zstd
    • Desktop integration enabled

Managing Configuration

View config:

soar config

Edit config:

soar config -e

Use custom config:

soar -c /path/to/config.toml [subcommand]

Environment Variables

VariableDescription
SOAR_CONFIGCustom config file path
SOAR_ROOTRoot directory override (affects all profiles)
SOAR_CACHECache directory override
SOAR_BINBinary directory override
SOAR_DBDatabase path override
SOAR_PACKAGESPackages directory override
SOAR_REPOSITORIESRepositories directory override
SOAR_PORTABLE_DIRSPortable directories path override
RUST_LOGDebug logging level (debug, info, trace)

Note: Environment variables take precedence over configuration file settings and profile paths.

Common Issues

Invalid TOML Syntax

Check for unclosed brackets, missing quotes, or duplicate names. Use soar config to validate.

Command Not Found

Add bin_path to your PATH in ~/.bashrc or ~/.zshrc.

Repository Not Syncing

Run soar sync manually. Check network connectivity and repository URLs.

Signature Verification Failed

Verify the pubkey URL is correct. Run soar sync to update keys.

Garbled Output

Switch to classic display mode:

[display]
progress_style = "classic"
icons = false

Profiles

Profiles are isolated package environments that allow you to maintain separate package sets for different purposes. Each profile has its own root directory and package storage.

Profile Configuration

Each profile is defined in your Soar configuration file (~/.config/soar/config.toml for user, /etc/soar/config.toml for system) under a [profile.<name>] section.

Profile Structure

[profile.<name>]
root_path = "/path/to/profile/root"
packages_path = "/path/to/packages"  # Optional
  • root_path (required): Root directory for the profile. Defaults to ~/.local/share/soar or $SOAR_ROOT/soar if not in system mode.
  • packages_path (optional): Custom location for package storage. If not set, defaults to <root_path>/packages.

Path Resolution Priority

Soar resolves paths in this order (highest priority first):

  1. Environment variables (SOAR_BIN, SOAR_DB, SOAR_CACHE, SOAR_PACKAGES, SOAR_REPOSITORIES, SOAR_PORTABLE_DIRS)
  2. Global configuration overrides (bin_path, db_path, cache_path, etc. in the root of config.toml)
  3. Profile-specific paths (computed from root_path)
graph TD
    A["Path requested
(e.g. bin_path)"] --> B{"Environment variable set?
(e.g. SOAR_BIN)"} B -->|Yes| C["Use env var value"] B -->|No| D{"Global config override set?
(e.g. bin_path in config.toml)"} D -->|Yes| E["Use global config value"] D -->|No| F["Compute from profile
root_path + /bin"] style C fill:#1c2128,stroke:#3fb9a2,color:#e6edf3 style E fill:#1c2128,stroke:#d29922,color:#e6edf3 style F fill:#1c2128,stroke:#58a6ff,color:#e6edf3

Important: Global configuration paths and environment variables take precedence over profile-computed paths. This means if you set bin_path in the global config or SOAR_BIN environment variable, it will be used instead of the profile’s <root_path>/bin.

Computed Paths

From the root_path, Soar automatically derives these paths (unless overridden):

PathComputed AsCan Override With
Packages<root_path>/packages (or packages_path if set)SOAR_PACKAGES env var
Binaries<root_path>/binbin_path config or SOAR_BIN env var
Database<root_path>/dbdb_path config or SOAR_DB env var
Cache<root_path>/cachecache_path config or SOAR_CACHE env var
Repositories<root_path>/reposrepositories_path config or SOAR_REPOSITORIES env var
Portable Dirs<root_path>/portable-dirsportable_dirs config or SOAR_PORTABLE_DIRS env var

Minimal Configuration

[profile.default]
root_path = "~/.local/share/soar"

This creates:

  • ~/.local/share/soar/packages/ - Installed packages
  • ~/.local/share/soar/bin/ - Binary symlinks (unless overridden globally)
  • ~/.local/share/soar/cache/ - Download cache (unless overridden globally)
  • ~/.local/share/soar/db/ - Package database (unless overridden globally)

Custom Packages Path

[profile.production]
root_path = "/opt/soar/production"
packages_path = "/opt/soar/production/packages"

Using Profiles

Specifying a Profile

Use the --profile <name> flag with any Soar command:

# Install to specific profile
soar --profile dev install neovim
soar --profile testing install ripgrep

# List packages in a profile
soar --profile dev list

# Remove from a profile
soar --profile testing remove ripgrep

# Update packages in a profile
soar --profile dev update

Environment Variable Override

The SOAR_ROOT environment variable overrides the root_path setting for any profile:

SOAR_ROOT=/tmp/test-soar soar install neovim

System Mode

Use the --system flag (-S) to operate in system-wide mode. This changes the config location to /etc/soar/config.toml and typically requires root privileges:

sudo soar --system install git
sudo soar --system --profile global add node

Profile Examples

Development vs Production

# ~/.config/soar/config.toml
[profile.dev]
root_path = "~/dev-soar"

[profile.production]
root_path = "~/prod-soar"
# Install development tools
soar --profile dev install rustc cargo node

# Install production-grade tools
soar --profile production install nginx postgresql

System-Wide Profile

# /etc/soar/config.toml
[profile.global]
root_path = "/opt/soar"
sudo soar --system --profile global install git

Directory Structure

Profile with root_path = "~/.local/share/soar":

~/.local/share/soar/
├── bin/              # Symlinks to package binaries
├── cache/            # Download cache
├── db/               # Package database
├── packages/         # Installed packages
├── repos/            # Repository metadata
└── portable-dirs/    # Portable app data

Summary

Profiles provide simple, file-based environment isolation:

  • Configuration: Define profiles in config.toml with root_path and optional packages_path
  • Usage: Specify profiles with --profile <name> flag
  • Path Priority: Environment variables > global config overrides > profile-computed paths
  • Computed Paths: bin, db, cache, repos, portable-dirs are automatically derived from root_path unless overridden
  • System Mode: Use --system flag for system-wide installations
  • Environment Override: SOAR_ROOT overrides profile root_path at runtime

CLI Reference

Global CLI options available in Soar.

Quick Reference

OptionShortDescription
--verbose-vIncrease output verbosity
--quiet-qSuppress all output except errors
--json-jOutput results in JSON format
--no-color-Disable colored output
--no-progress-Disable progress bars
--profile-pUse a specific profile
--config-cSpecify custom config file path
--proxy-PSet HTTP/HTTPS proxy server
--header-HAdd custom HTTP headers
--user-agent-ASet custom User-Agent string
--system-SOperate in system-wide mode (requires root)

Verbosity Control

--verbose / -v

Increase output verbosity. Can be used multiple times (-vv, -vvv).

soar -v install neovim
soar -vv sync

--quiet / -q

Suppress all non-error output.

soar -q install nodejs

Output Format

--json / -j

Output results in JSON format for parsing.

soar --json query neovim
soar --json search python | jq '.[] | .name'

Display Options

--no-color

Disable colored output.

soar --no-color install ffmpeg

--no-progress

Disable progress bars.

soar --no-progress sync > sync.log

Configuration

--profile / -p

Use a specific profile.

soar --profile work install vscode

Profiles defined in ~/.config/soar/config.toml:

[profile.work]
root_path = "/opt/soar-work"

--config / -c

Specify custom configuration file path.

soar --config /path/to/config.toml install neovim

Network Options

--proxy / -P

Set HTTP/HTTPS proxy server.

soar --proxy http://proxy.example.com:8080 install python
soar --proxy http://user:pass@proxy.example.com:8080 sync

--header / -H

Add custom HTTP headers.

soar --header "Authorization: Bearer mytoken" sync
soar -H "X-Api-Key: secret123" install package

--user-agent / -A

Set custom User-Agent string.

soar --user-agent "MyApp/1.0" install python

System Mode

--system / -S

Operate in system-wide mode (requires root).

sudo soar --system install docker

System paths:

  • Config: /etc/soar/config.toml
  • Root: /opt/soar
  • Binaries: /opt/soar/bin

Common Combinations

Scripting:

soar --json --quiet install python

Debugging:

soar -vv --no-progress install neovim

CI/CD with Proxy:

soar --json --proxy http://proxy.corp.com:8080 sync

System Installation:

sudo soar --system install docker

Environment Variables

VariablePurposeExample
HTTP_PROXYSet HTTP/HTTPS proxyexport HTTP_PROXY=http://proxy:8080
SOAR_CONFIGCustom config file pathexport SOAR_CONFIG=/path/to/config.toml
NO_COLORDisable colored outputexport NO_COLOR=1
SOAR_ROOTOverride root directoryexport SOAR_ROOT=/custom/soar
SOAR_BINOverride bin pathexport SOAR_BIN=/custom/bin
SOAR_DBOverride database pathexport SOAR_DB=/custom/db
SOAR_CACHEOverride cache pathexport SOAR_CACHE=/custom/cache
SOAR_PACKAGESOverride packages pathexport SOAR_PACKAGES=/custom/packages
SOAR_REPOSITORIESOverride repositories pathexport SOAR_REPOSITORIES=/custom/repos
SOAR_PORTABLE_DIRSOverride portable dirs pathexport SOAR_PORTABLE_DIRS=/custom/portable
SOAR_STEALTHUse default config without reading fileexport SOAR_STEALTH=1
SOAR_NIGHTLYForce nightly update channelexport SOAR_NIGHTLY=1

See Also

Package Management

Soar provides a comprehensive set of commands for managing packages on your system. This section covers all package management operations available in Soar.

Declarative Management

Declarative Packages

Define packages in a configuration file and apply them:

  • Configuration file: ~/.config/soar/packages.toml
  • Apply packages: soar apply
  • Prune unlisted: soar apply --prune

Core Operations

Installing Packages

Install packages using various methods:

  • Basic installation: soar install <package>
  • pkg_id specific: soar install <package>#<pkg_id>
  • From URL: soar install <url>
  • Multiple packages: soar install package1 package2
  • Portable installation (for AppImages): soar install <package> --portable

Removing Packages

Remove installed packages:

  • Basic removal: soar remove <package>
  • Multiple packages: soar remove package1 package2

Updating Packages

Keep your packages up to date:

  • Update all packages: soar update
  • Update specific packages: soar update package1 package2

Package Discovery

Searching Packages

Find packages in repositories:

  • Basic search: soar search <query>
  • Case-sensitive search: soar search <query> --case-sensitive
  • Detailed package info: soar query <package>

Listing Packages

View available and installed packages:

  • List all available packages: soar list
  • List installed packages with sizes: soar info

Package Inspection

Inspection Commands

Inspect package details and build information:

  • View build logs: soar log <package>
  • Inspect build scripts: soar inspect <package>
  • Query package details: soar query <package>

Advanced Operations

Using Package Variants

Switch between different variant of installed packages:

  • Switch family: soar use <package>

Running Packages

Execute packages without installation:

  • Run package: soar run <package> [args]

System Maintenance

Perform system maintenance and repository operations:

Maintenance Commands

  • Clean cache and broken files: soar clean
  • Sync repositories: soar sync
  • View environment: soar env

Declarative Package Management

Soar supports declarative package management through packages.toml. Define your desired packages and apply them in one command to maintain consistent environments across machines.

Configuration File

Create packages.toml at ~/.config/soar/packages.toml:

soar defpackages

File Structure

The packages.toml file supports two top-level sections:

  • [defaults] - Default settings applied to all packages
  • [packages] - Package specifications
[defaults]
profile = "default"
binary_only = false
install_patterns = ["!*.log", "!SBUILD"]

[packages]
# Package specifications go here

Defaults Section

The [defaults] section sets default values that apply to all packages unless overridden.

FieldTypeDescription
profileStringDefault profile to install packages to
binary_onlyBooleanOnly extract binaries, skip other files
install_patternsArray of StringsFile patterns to include/exclude during installation

Packages Section

The [packages] section contains package specifications in multiple formats.

Simple String Format

[packages]
# Latest version (never pinned)
bat = "*"

# Specific version (auto-pinned for repo packages)
ripgrep = "14.1.0"

# Using table format (auto-pinned for repo packages)
fd = { version = "9.0.0" }

# Remote packages are not auto-pinned
remote-tool = { url = "https://example.com/tool.tar.gz" }

Version Resolution and Pinning

Spec FormatVersionPinnedNotes
pkg = "*"LatestNoAlways installs latest version
pkg = "1.2.3"1.2.3Yes (repo only)Pinned for repository packages
pkg = { version = "1.2.3" }1.2.3Yes (repo only)Pinned for repository packages
pkg = { url = "..." }DetectedNoRemote packages not auto-pinned
pkg = { version = "1.2.3", pinned = false }1.2.3NoExplicitly override pinning
pkg = { url = "...", pinned = true }DetectedYesExplicitly pin remote package

Key points:

  • Repository packages with specific versions are automatically pinned
  • Remote packages (url/github/gitlab) are never auto-pinned unless you explicitly set pinned = true
  • Pinned packages are skipped during auto-update operations
  • Version * always resolves to latest and is never pinned
  • After installing a package with version "*", soar updates your packages.toml with the specific version installed

Detailed Format

[packages.my_package]
pkg_id = "pkg-bin"
repo = "bincache"
version = "1.0.0"
pinned = true
portable = { home = "~/.pkg", config = "~/.pkg/config" }

Package Options Reference

FieldTypeDescription
versionStringPackage version to install ("*" for latest)
pkg_idStringPackage variant/family identifier
repoStringInstall from a specific repository
urlStringInstall directly from a URL
pinnedBooleanPrevent automatic updates (default: false)
profileStringInstall to a specific profile
githubStringGitHub repo in owner/repo format
gitlabStringGitLab repo in owner/repo format
asset_patternStringGlob pattern to match release assets
tag_patternStringGlob pattern to match release tags
include_prereleaseBooleanInclude pre-release versions
version_commandStringCustom command to fetch latest version and download URL
binary_onlyBooleanOnly extract binaries, skip other files
binariesArrayMap multiple binaries to custom names (see Binary Mappings)
install_patternsArrayFile patterns to include/exclude
portableObjectConfigure portable directories (see Portable)
hooksObjectLifecycle hooks (see Hooks)
buildObjectBuild from source (see Build From Source)
sandboxObjectSecurity sandbox (see Sandbox)
pkg_typeStringOverride package type detection
entrypointStringEntry point executable name
nested_extractStringPath to nested archive to extract
extract_rootStringSubdirectory to treat as root

Binary Mappings

Map multiple executables within a package to custom symlink names. The source field supports glob patterns to match multiple files at once.

FieldTypeDescription
sourceStringPath or glob pattern to match executables within package
link_asStringCustom symlink name (optional, defaults to the source filename)

When a glob matches multiple files, each is symlinked using its original filename. link_as is only used when a single file matches.

Hooks

Execute commands at various stages of the package lifecycle:

HookDescription
post_downloadRun after download, before extraction
post_extractRun after extraction
post_installRun after symlinks created
pre_removeRun before package removal

Available environment variables: $INSTALL_DIR, $BIN_DIR, $PKG_NAME, $PKG_ID, $PKG_VERSION

[packages.myapp]
url = "https://example.com/myapp-1.0.0.tar.gz"
hooks = { post_install = "myapp --init" }

Build From Source

FieldTypeDescription
commandsArrayShell commands to run sequentially
dependenciesArrayRequired tools (checked via which)

Available environment variables: $INSTALL_DIR, $BIN_DIR, $PKG_NAME, $PKG_ID, $PKG_VERSION, $NPROC

[packages.custom-tool]
url = "https://example.com/tool-1.0.0.tar.gz"
build = {
  commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"]
  dependencies = ["gcc", "make"]
}

Sandbox

Restrict filesystem and network access for hooks and build commands using Linux’s Landlock LSM (kernel 5.13+).

FieldTypeDescription
requireBooleanFail if Landlock is unavailable (default: false)
fs_readArrayAdditional readable paths
fs_writeArrayAdditional writable paths
networkBooleanAllow network access (requires kernel 6.7+)
[packages.untrusted-tool]
url = "https://example.com/tool-1.0.0.tar.gz"
sandbox = { require = true, network = false }

Portable

Configure portable mode for AppImage, FlatImage, RunImage, and Wrappe packages. Creates symlinks from expected data directories to custom locations.

FieldTypeDescription
pathStringSets both home and config to the same path
homeStringPortable home directory
configStringPortable config directory
shareStringPortable share directory
cacheStringPortable cache directory

Format support: AppImage/RunImage (all fields), FlatImage (only config), Wrappe (only path)

[packages.obsidian]
url = "https://example.com/obsidian.AppImage"
portable = { path = "~/.obsidian-data" }

GitHub/GitLab Integration

Install packages directly from GitHub or GitLab releases:

[packages]
# From GitHub releases
gh-release = { github = "cli/cli" }

# With asset pattern
gh-release = {
  github = "cli/cli",
  asset_pattern = "gh_*_linux_amd64.tar.gz"
}

# With tag pattern
gh-beta = {
  github = "owner/repo",
  tag_pattern = "v2*",
  include_prerelease = true
}

# From GitLab
gl-release = { gitlab = "gitlab-org/gitlab" }

Important: asset_pattern and tag_pattern use glob patterns, not regex. Supported patterns include:

  • * - matches any sequence of characters
  • ? - matches any single character
  • [abc] - matches any character in the set
  • [!abc] - matches any character not in the set

Version Command

The version_command field is used for custom URL packages to detect what version is available from a remote source BEFORE installation. This tells soar what version it would download if it were to install the package.

When It Runs

The version_command runs BEFORE installation for custom URL packages to:

  1. Detect remote version: Query the remote source to find what version is available
  2. Generate download URL: Optionally provide the exact download URL for that version
  3. Report size: Optionally provide the download size for progress display

This is primarily useful for custom URL packages where the download URL needs the version number substituted, but the version isn’t embedded in the URL you configure.

Output Format

The version_command must output exactly 3 lines:

<remote_version>
<download_url_for_that_version>
<size_in_bytes>
  • Line 1 (required): The version available at the remote source (e.g., 1.2.3 or v1.2.3)
  • Line 2 (optional): Download URL for that version. If omitted or empty, soar uses the url field with {version} placeholder substituted
  • Line 3 (optional): Size of download in bytes for progress display

When to Use version_command

Use version_command for custom URL packages when:

  1. Your URL uses {version} placeholder but you need to dynamically discover what version is available
  2. The remote source has a version API or endpoint you can query
  3. You need to parse a download page to extract version information
  4. You want to provide a custom download URL that differs from the template

Note: For GitHub/GitLab packages, soar already handles version detection automatically. You typically don’t need version_command unless you have special requirements.

Examples

Query GitHub API for latest release:

[packages.my-tool]
url = "https://example.com/downloads/my-tool-{version}.tar.gz"
version_command = """
  curl -s https://api.github.com/repos/owner/my-tool/releases/latest | \\
  jq -r '.tag_name'
"""

This fetches the latest release tag from GitHub and outputs it. Soar then uses that version to substitute into the url field.

Query a version.json endpoint:

[packages.api-tool]
url = "https://example.com/downloads/tool-{version}.zip"
version_command = """
  VERSION=$(curl -s https://example.com/api/tool/latest | jq -r '.version')
  echo "$VERSION"
  echo "https://example.com/downloads/tool-$VERSION.zip"
  echo "$(curl -sI https://example.com/downloads/tool-$VERSION.zip | grep -i content-length | awk '{print $2}' | tr -d '\\r')"
"""

This queries a version.json API endpoint, extracts the version, constructs the download URL, and even fetches the file size.

Parse a download page for version:

[packages.scrape-tool]
url = "https://example.com/downloads/tool-{version}.tar.gz"
version_command = """
  curl -s https://example.com/downloads.html | \\
  grep -oP 'tool-\\d+\\.\\d+\\.\\d+\\.tar\\.gz' | \\
  sed 's/tool-//' | sed 's/.tar.gz//' | \\
  sort -V | tail -n1
"""

This scrapes the downloads page, extracts version numbers from filenames, and returns the latest one.

Strip version prefix:

[packages.custom-tool]
url = "https://example.com/{version}/download.tar.gz"
# Remote returns "v1.2.3" but we want "1.2.3"
version_command = """
  VERSION=$(curl -s https://example.com/latest | grep -oP 'v\\d+\\.\\d+\\.\\d+')
  echo "${VERSION#v}"  # Strip 'v' prefix
"""

Best Practices

  1. Use jq for JSON APIs: More reliable than grep/grep for parsing

    version_command = "curl -s https://api.example.com/latest | jq -r '.version'"
    
  2. Handle missing API endpoints gracefully: Return a fallback version

    version_command = "curl -s https://example.com/version.txt || echo '0.0.0'"
    
  3. Use -s flag with curl: Suppress progress bars for clean output

    version_command = "curl -s https://example.com/latest-version"
    
  4. Test your command manually: Verify it outputs exactly 3 lines

    curl -s https://api.github.com/repos/owner/repo/releases/latest | jq -r '.tag_name'
    echo ""
    echo ""
    
  5. Consider rate limiting: Add delays or respect rate limits when querying APIs frequently

Simple vs Detailed Configuration

When to Use Simple Version Strings

Simple strings are ideal for straightforward package installations:

[packages]
# Latest version from default repository
bat = "*"

# Specific version (auto-pinned for repo packages)
ripgrep = "14.1.0"

# Inline table for minor customization
fd = { version = "9.0.0", repo = "bincache" }

Use simple strings when:

  • Installing from the default repository with standard settings
  • You only need to specify version and optionally repo/profile
  • No custom asset patterns, hooks, or build configuration needed
  • Quick one-line configuration is sufficient

When to Use Detailed Tables

Full table format is needed for advanced configurations:

[packages.myapp]
github = "owner/repo"
asset_pattern = "myapp_*_linux_amd64.tar.gz"
hooks = { post_install = "myapp --init" }
pinned = true

Use detailed tables when you need:

  • GitHub/GitLab releases with asset_pattern, tag_pattern, or include_prerelease
  • Direct URL installation with url
  • Version fetching via version_command for URL packages
  • Build from source with build commands and dependencies
  • Multiple binary mappings with binaries
  • Lifecycle hooks (post_install, pre_remove, etc.)
  • Sandbox restrictions for untrusted packages
  • Portable mode for AppImage/FlatImage/RunImage/Wrappe
  • Custom install patterns or binary_only
  • Explicit pinning control (especially for URL packages)

Decision Guide

RequirementFormatExample
Latest version from repoSimple stringpkg = "*"
Specific version from repoSimple stringpkg = "1.2.3"
From custom repositoryInline tablepkg = { version = "*", repo = "custom" }
GitHub/GitLab releasesFull tableSee GitHub/GitLab sections above
Direct URL downloadFull tablepkg = { url = "https://..." }
Build from sourceFull tableSee BuildConfig section
Multiple binariesFull tableSee BinaryMapping section
Post-install setupFull tablepkg = { version = "1.0", hooks = {...} }
Security sandboxingFull tablepkg = { version = "1.0", sandbox = {...} }

Complete Examples

Minimal Configuration

[packages]
bat = "*"
ripgrep = "*"
soar = "0.5.2"
7z = { repo = "bincache" }

Advanced Configuration

[defaults]
profile = "default"
binary_only = false
install_patterns = ["!*.log", "!SBUILD"]

[packages]
bat = "*"

obsidian = {
  version = "1.5.0"
  pinned = true
  portable = { home = "~/.obsidian-data" }
}

gh-cli = {
   github = "cli/cli"
   asset_pattern = "gh_*_linux_amd64.tar.gz"
 }

custom-tool = {
  url = "https://example.com/tool-1.0.0.tar.gz"
  build = {
    commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"]
    dependencies = ["gcc", "make"]
  }
}

untrusted-tool = {
  url = "https://example.com/tool-1.0.0.tar.gz"
  hooks = { post_install = "$INSTALL_DIR/setup.sh" }
  sandbox = { require = true, network = false }
}

Applying Packages

Basic Apply

To install all packages defined in your packages.toml:

soar apply

Apply Options

OptionFlagDescription
Prune--pruneRemove packages not listed in packages.toml
Dry run--dry-runShow what would be done without making changes
Yes--yesAuto-confirm all prompts
Config--packages <path>Use custom packages.toml path
No verify--no-verifySkip signature verification (security risk)

Pruning Unlisted Packages

To also remove packages that are not listed in your packages.toml:

soar apply --prune

Warning: The --prune flag will remove any installed packages not defined in your packages.toml. Make sure your configuration includes all packages you want to keep.

Dry Run

Preview what would be installed without making changes:

soar apply --dry-run

Custom Config File

Use a packages.toml from a custom location:

soar apply --packages /path/to/custom-packages.toml

Defpackages Command

Generate a template packages.toml with examples:

soar defpackages

This creates ~/.config/soar/packages.toml with commented examples showing all available options.

Environment Override

You can override the default packages.toml path using the SOAR_PACKAGES_CONFIG environment variable:

export SOAR_PACKAGES_CONFIG=/path/to/my-packages.toml
soar apply

Best Practices

  • Version Pinning: Pin versions for production tools, use * for development
  • Profiles: Set default profile in [defaults], override per-package if needed
  • Portable Mode: Use for AppImage/FlatImage/RunImage/Wrappe packages to keep data self-contained
  • Hooks: Use post_install for setup, pre_remove for cleanup
  • Sandbox: Enable for untrusted tools to restrict filesystem and network access
  • Dry Run: Always run soar apply --dry-run to verify changes
  • Version Commands: Use version_command for URL packages to enable automatic updates

For troubleshooting, see Health Check

Installing Packages

Soar provides several flexible ways to install packages. This guide covers all installation methods and options.

Installation Flow

graph TD
    A["soar install <input>"] --> B{"Input type?"}
    B -->|"package name"| C["Search repositories"]
    B -->|"name#pkg_id"| D["Search specific family"]
    B -->|"name:repo"| E["Search specific repo"]
    B -->|"URL"| F["Download from URL"]

    C --> G{"Multiple matches?"}
    D --> G
    E --> H["Download & Install"]
    F --> H

    G -->|"Yes"| I{"--yes flag?"}
    G -->|"No"| H
    I -->|"Yes"| J["Select first match"]
    I -->|"No"| K["Prompt user to select"]
    J --> H
    K --> H

    style A fill:#161b22,stroke:#58a6ff,color:#e6edf3
    style H fill:#1c2128,stroke:#3fb9a2,color:#e6edf3

Basic Installation

To install a package, use either the install command or its aliases:

# Using install command
soar install <package>

# Using shorter alias
soar i <package>

# Using add alias
soar add <package>

Example: Install the soar package

soar add soar

Installing from Specific pkg_id

Packages can be organized into pkg_id (like family). To install a package from a specific pkg_id:

soar add <package>#<pkg_id>

Example: Install the cat package from the git.busybox.net.busybox.standalone.glibc pkg_id. Yep, a really long pkg_id.

soar add cat#git.busybox.net.busybox.standalone.glibc

Installing from Specific Repository

To install a package from a specific repository:

soar add <package>:<repository_name>

Example: Install the 7z package from the bincache repository

soar add 7z:bincache

Installing from URL

You can install packages directly from a URL:

soar add <url>

Example: Install an AppImage from a URL

soar add https://example.com/releases/myapp-1.0.0.appimage

Overriding Package Metadata

When installing from a URL, Soar attempts to automatically detect package metadata. You can override this behavior using the following flags:

FlagDescription
--nameOverride the package name
--versionOverride the version
--pkg-typeOverride the package type (e.g., appimage, flatimage, archive)
--pkg-idOverride the package ID
--binary-onlyInstall only binaries, skip other files
--no-verifySkip checksum and signature verification
--portable [DIR]Set portable dir for home & config (optional value)
--portable-home [DIR]Set custom home directory (optional value)
--portable-config [DIR]Set custom config directory (optional value)
--portable-share [DIR]Set custom share directory (optional value)
--portable-cache [DIR]Set custom cache directory (optional value)
--showShow all available variants for interactive selection

Basic Example:

soar add https://example.com/app.appimage --name myapp --version 2.0.0

Portable Installation:

soar add https://example.com/app.AppImage \
  --name myapp \
  --portable-home ~/myapp

Installing Multiple Packages

To install multiple packages, list them after the command:

soar add <package1> <package2> <package3>

Example: Install the bat and 7z packages

soar add bat 7z

Pin package to specific version

To pin package at specific version:

soar add <package>@<version>

Example: Install the soar package and pin at version 0.5.2.

soar add soar@0.5.2

Warning: Currently there is no way to unpin the package. This will be introduced gradually.

Installing All Packages provided by a pkg_id

To install all the packages provided by a pkg_id git.busybox.net.busybox.standalone.glibc:

soar add '#git.busybox.net.busybox.standalone.glibc'

OR, if you don’t know full pkg_id but know cat is in it. This will search for all pkg_ids cat is in and prompt you to choose one:

soar add 'cat#all'

Portable Installation

Portable mode creates symlinks for application data directories (home, config, share, cache) to custom locations. This keeps application data self-contained or allows running from removable media.

Warning: Portable mode only works for AppImage, FlatImage, RunImage, and Wrappe packages. Static binaries and archive packages do not support portable mode.

To install a package in portable mode:

soar add <package> --portable

You can specify custom directories for different data types:

FlagDescription
--portable [DIR]Set base portable directory (applies to home and config). Optional value: if no directory specified, uses package installation directory
--portable-home [DIR]Custom home directory (creates symlink). Optional value
--portable-config [DIR]Custom config directory (creates symlink). Optional value
--portable-share [DIR]Custom share directory (creates symlink). Optional value
--portable-cache [DIR]Custom cache directory (creates symlink). Optional value

Example: Install with a custom home directory

soar add obsidian.AppImage --portable-home ~/.obsidian-data

Example: Install with multiple custom directories

soar add myapp.AppImage --portable-home ~/myapp --portable-config ~/myapp/config --portable-share ~/myapp/share --portable-cache ~/myapp/cache

Note: Portable options create symlinks from the package’s expected directories to your custom locations. These settings are stored in the database and reused on reinstallation.

Force Installation

To force installation even if the package already exists, use the --force flag:

soar add <package> --force

Example: Install the bat package even if it already exists

soar add bat --force

Binary-Only Installation

By default, Soar extracts all files from a package. The --binary-only flag skips extracting non-essential files to save disk space:

soar add <package> --binary-only

This flag excludes:

  • *.png and *.svg (icon files)
  • *.desktop (desktop entry files)
  • LICENSE (license files)
  • CHECKSUM (checksum files)

Example: Install ripgrep without icons, desktop files, and license

soar add ripgrep --binary-only

Note: This option is useful for minimal installations. However, excluding desktop files (*.desktop) means the package won’t appear in your system’s application menu.

Suppress Package Notes

Some packages display important information after installation. To suppress these notes, use the --no-notes flag:

soar add <package> --no-notes

Example: Install neovim without displaying post-installation notes

soar add neovim --no-notes

Note: Package notes often contain critical setup instructions or configuration tips. Use this flag with caution.

Interactive Installation

By default, Soar automatically installs packages. To explicitly enable interactive prompts (for example, to choose between multiple versions or variants), use the --ask flag:

soar add <package> --ask

This is the opposite of --yes and ensures Soar will always prompt for confirmation before proceeding with installation.

Skip Signature Verification

By default, Soar verifies package signatures for security. To skip signature verification (not recommended unless you trust the source), use the --no-verify flag:

soar add <package> --no-verify

Security Warning: Skipping signature verification exposes you to potentially compromised packages. Only use --no-verify with packages from trusted sources or during testing/development.

Example: Install a package from a trusted development build

soar add https://internal.example.com/builds/myapp.appimage --no-verify

Package ID Override

To explicitly specify the package ID (useful when multiple packages share the same name), use the --pkg-id flag:

soar add <package> --pkg-id <package_id>

Example: Install cat from a specific package ID

soar add cat --pkg-id git.busybox.net.busybox.standalone.glibc

This is equivalent to using the cat#git.busybox.net.busybox.standalone.glibc syntax but can be more readable in scripts.

Show Package Information

To interactively browse and select package variants before installing, use the --show flag:

soar add <package> --show

This opens an interactive picker that displays:

  • All available versions and variants of the package
  • [installed] marker next to already-installed versions
  • Package details (name, version, repository, pkg_id)

Example: Browse all bat variants interactively

soar add bat --show

Note: Unlike a non-interactive display, --show always presents an interactive selection menu. You can choose which variant to install or cancel without installing anything.

Non-Interactive Installation

By default, Soar prompts for confirmation before installing packages if multiple packages are found for the given query. To skip this prompt, use the --yes flag:

soar add <package> --yes

Example: Install the cat package without confirmation

soar add cat --yes

Note: The --yes flag is useful for non-interactive installations, but it’s generally recommended to use it with caution. It will install the first package if multiple packages are found.

Advanced Scenarios

Batch Installation

You can combine multiple installation options for complex scenarios:

soar add bat --yes --no-notes
soar add ripgrep --yes --binary-only

Portable Application Setup

For AppImage/FlatImage/RunImage/Wrapper applications that need to be completely self-contained (e.g., on a USB drive):

soar add obsidian.AppImage \
  --portable-home /media/usb/obsidian/home \
  --portable-config /media/usb/obsidian/config

Installing All Packages from a pkg_id

To install all packages provided by a specific package ID family:

soar add '#git.busybox.net.busybox.standalone.glibc'

Or if you know one package name but want to see all pkg_ids it belongs to:

soar add 'cat#all'

Troubleshooting

Package Not Found

Check package name spelling, sync repositories, or try installing from URL directly:

soar search <name>
soar sync

Multiple Packages Found

Use --ask to choose interactively, specify repository with <package>:<repo>, or use --yes for first match.

Permission Denied

Verify profile permissions or use sudo with --system mode.

Portable Mode Not Working

Portable mode only works for AppImage, FlatImage, RunImage, and Wrappe packages. Static binaries and archives are not supported.

For more troubleshooting, see Health Check

Remove Packages

Soar provides straightforward commands for removing installed packages from your system. This guide covers all removal options, what happens during removal, and troubleshooting tips.

Usage

To remove a package, use either the remove command or its aliases:

Removing Single Package

# Using remove command
soar remove <package>

# Using shorter alias
soar r <package>

# Using del alias
soar del <package>

Example: Remove 7z

soar remove 7z

Command Options

The remove command supports the following options:

OptionDescription
--yesSkip confirmation prompts. Automatically selects the first option when multiple packages match.
--allRemove all installed variants of the specified package across different pkg_ids.

Using –yes

Skip interactive prompts when removing packages:

# Remove without confirmation
soar remove --yes 7z

# Automatically select first match when multiple variants exist
soar remove --yes bat

Using –all

Remove all installed variants of a package:

# Remove all versions of bat from all pkg_ids
soar remove --all bat

# Remove with --yes to skip bulk confirmation
soar remove --all --yes cat

Warning: Using --all will remove ALL installed variants of the package, including those from different repositories and pkg_ids. Use with caution.

Removing Multiple Packages

Remove multiple packages in a single command:

soar remove <package1> <package2> <package3>

Example: Remove 7z and bat

soar remove 7z bat

Warning: If you just provide the package name without pkg_id and multiple packages match, you’ll be prompted to select ONE package to remove. Use --all to remove all variants.

Removing Package From Specific pkg_id

soar remove <package>#<pkg_id>

Example: Remove cat from git.busybox.net.busybox.standalone.glibc pkg_id.

# Remove from specific pkg_id
soar remove cat#git.busybox.net.busybox.standalone.glibc

Removing all packages from a specific pkg_id

Example: Remove all packages from a specific pkg_id.

soar remove '<name>#all'

This will search for all pkg_ids cat is in and prompt you to choose one:

soar remove 'cat#all'

After selecting a pkg_id, all packages from that pkg_id will be removed.

What Happens During Removal

When you remove a package, Soar performs cleanup operations:

  1. Pre-Remove Hook (if configured)
  2. Binary Symlink Removal from ~/.local/share/soar/bin
  3. Provides Symlink Cleanup for alternative names
  4. Desktop Entry Removal from ~/.local/share/applications
  5. Icon Symlink Cleanup from ~/.local/share/icons
  6. Package Directory Removal from ~/.local/share/soar/packages
  7. Cache Handling - Download cache preserved (use soar clean --cache to reclaim)
  8. Database Cleanup - Removes package record and portable entries
graph TD
    A["soar remove pkg"] --> B["Run pre-remove hook"]
    B --> C["Remove binary symlinks
(~/.local/share/soar/bin)"] C --> D["Remove provides symlinks"] D --> E["Remove desktop entries
(~/.local/share/applications)"] E --> F["Remove icon symlinks
(~/.local/share/icons)"] F --> G["Remove package directory
(~/.local/share/soar/packages)"] G --> H["Clean database records"] H --> I["Done ✓"] style A fill:#161b22,stroke:#58a6ff,color:#e6edf3 style I fill:#1c2128,stroke:#3fb9a2,color:#e6edf3

Example Output:

Removed 7z#upstream.release:official (24.08)
  - Removed binary: ~/.local/share/soar/bin/7z
  - Removed directory: ~/.local/share/soar/packages/7z-24.08
  - Reclaimed 2.3 MiB

Partial vs Complete Removal

Complete Removal

A complete removal occurs when:

  • The package was successfully installed (is_installed = true)
  • All files and symlinks are properly cleaned up
  • The package is removed from the database

This is the normal and expected removal process.

Partial Removal (Broken Packages)

A partial or incomplete installation can occur when:

  • The installation process was interrupted (network failure, system crash)
  • Disk space ran out during installation
  • The package was manually deleted from the filesystem

These are marked as broken packages in Soar’s database (is_installed = false).

Identifying Broken Packages

To check for broken or incomplete installations:

soar health

Example output showing broken packages:

Broken Packages (1):
  7z#upstream.release:official /home/user/.local/share/soar/packages/7z-24.08

Removing Broken Packages

To remove all broken packages:

soar clean --broken

This command:

  • Lists all broken packages in the database
  • Removes their directories (if they still exist)
  • Removes any leftover symlinks
  • Cleans up database entries

Troubleshooting

Stuck or Incomplete Removals

Check system health and fix broken symlinks:

soar health
soar clean --broken-symlinks

Package Won’t Remove

Check file permissions, ensure package isn’t running, and use verbose mode:

ls -la ~/.local/share/soar/packages/
pgrep -a <package>
soar --verbose remove <package>

For more help, see Health Check

Manual Cleanup

For manual cleanup of stuck packages:

  1. Find the package directory:

    soar info | grep <package>
    
  2. Remove the directory manually:

    rm -rf ~/.local/share/soar/packages/<package-directory>
    
  3. Remove symlinks manually:

    rm -f ~/.local/share/soar/bin/<package>
    
  4. Run health check:

    soar health
    
  5. Clean up any remaining broken symlinks:

    soar clean --broken-symlinks
    

Update Packages

Soar provides efficient commands to keep your packages up to date. This guide covers all update operations and options.

Quick Start

To update all installed packages to their latest versions:

soar update

To update specific packages:

soar update <package1> <package2>

Example: Update specific packages

soar update 7z bat

Update Options

The update command supports the following options:

OptionDescription
--askPrompt for confirmation before updating each package
--keepKeep the current version (only refresh metadata)
--no-verifySkip checksum and signature verification

Version Determination

Repository Packages

For packages installed from repositories, Soar determines the latest version from the package database:

soar update bat

This will update bat to the latest version available in the repository it was installed from.

Local Packages

Packages installed from URLs retain their installation specifications. Updates check for newer versions at the same URL or based on version detection:

soar update https://example.com/app.AppImage

Profile Handling

Warning: The profile flag has no effect on package installation path; it’ll use the profile used at the time of installation.

The update process respects the original installation profile. If a package was installed with a specific profile, updates will maintain that profile setting.

Update Options Details

Ask for Confirmation

To prompt for confirmation before updating each package:

soar update --ask
soar update <package> --ask

This is useful when you want to review changes before updating:

soar update --ask
# Soar will prompt for each package update

Keep Current Version

To refresh package metadata without updating to a newer version, use --keep:

soar update <package> --keep

This updates the package database entry but maintains the current installed version. Useful for:

  • Refreshing package information
  • Re-verifying installations
  • Testing without version changes

Skip Verification

To skip signature and checksum verification during updates (not recommended):

soar update <package> --no-verify

Security Warning: Skipping verification exposes you to potentially compromised updates. Only use with trusted sources.

Cross-Repository Update Behavior

Warning: The update process ignores updates from another repository than the one the package is installed from.

Important update behaviors:

  • Single Repository Source: A package always updates from the same repository it was installed from
  • No Repository Switching: Even if a newer version exists in a different repository, it won’t be used
  • Explicit Override: To switch repositories, use soar remove followed by soar add <package>:<new-repo>

Example: Update from the original repository

# Installed from 'official', will only check 'official' for updates
soar update bat

To update from a different repository:

# Remove from original repository
soar remove bat

# Install from new repository
soar add bat:bincache

Update Behavior Details

What Happens During Update

When you update a package, Soar:

  1. Checks for newer versions in the source repository
  2. Verifies signatures and checksums (unless --no-verify is used)
  3. Downloads the new version
  4. Backs up the current installation
  5. Extracts the new version
  6. Updates symlinks and database entries
  7. Removes the old version (if successful)
graph TD
    A["soar update"] --> B["Check source repository"]
    B --> C{"Newer version
available?"} C -->|"No"| D["Skip — already up to date"] C -->|"Yes"| E["Verify signatures & checksums"] E --> F["Download new version"] F --> G["Backup current installation"] G --> H["Extract & install new version"] H --> I["Update symlinks & database"] I --> J{"Success?"} J -->|"Yes"| K["Remove old version"] J -->|"No"| L["Restore from backup"] style D fill:#1c2128,stroke:#8b949e,color:#e6edf3 style K fill:#1c2128,stroke:#3fb9a2,color:#e6edf3 style L fill:#1c2128,stroke:#f85149,color:#e6edf3

Backup and Recovery

Soar maintains backups during updates:

# If update fails, the previous version remains intact
soar update bat

Batch Updates

Update multiple packages in one command:

soar update bat ripgrep fd
soar update --ask bat ripgrep fd

Best Practices

  1. Regular Updates: Keep packages up to date for security fixes and features

    soar update
    
  2. Test Before Production: Use --ask to review updates

    soar update --ask
    
  3. Verify Trust: Always verify package sources before updating

    soar info <package>
    
  4. Backup Important Data: For critical applications, backup data before updating

    soar update --ask <critical-app>
    
  5. Selective Updates: Update specific packages if concerned about compatibility

    soar update <package1> <package2>
    

Scenarios

Update All Packages

soar update

This updates all installed packages to their latest versions from their original repositories.

Update with Confirmation

soar update --ask

Review each package update before proceeding.

Update Specific Package

soar update ripgrep

Update only the ripgrep package.

Refresh Metadata Without Updating

soar update --keep

Update package metadata in the database without changing installed versions.

Update from Different Repository

# Current setup uses 'official' repository
soar remove bat

# Switch to 'bincache' repository
soar add bat:bincache

# Future updates will use 'bincache'
soar update bat

Troubleshooting

Update Fails with Signature Error

Verify the package source is trusted:

soar info <package>
soar update --no-verify <package>  # Only if source is trusted

Update Stuck or Slow

Check network connection and repository status:

soar sync
soar update <package>

Version Didn’t Change

Verify the package actually has a newer version available:

soar query <package>

Can’t Update from Different Repository

This is by design. Remove and reinstall from the new repository:

soar remove <package>
soar add <package>:<new-repo>

For more help, see Health Check

Search Packages

Soar provides powerful search capabilities to help you find the packages you need. This guide covers all search operations and features.

To search for packages, use the soar search command:

soar search <query>

Alternative aliases:

# Using shorter alias
soar s <query>

# Using find alias
soar find <query>

Example: Search for packages containing “bat”

soar search bat

Search Options

The search checks for the partial match in pkg_id, pkg_name, pkg and target from provides.

For exact case matching:

soar search <query> --case-sensitive

Example: Search with exact case

soar search Bat --case-sensitive

For exact matching (no partial matches):

soar search <query> --exact

Example: Find exact package name

soar search bat --exact

Result Limit

Limit the number of search results returned:

soar search <query> --limit <number>

Example: Return only top 10 results

soar search editor --limit 10

By default, Soar searches across all configured repositories. Search results display which repository each package comes from:

soar search bat

Results may include packages from multiple repositories:

bat#official:bincache
bat#official:official

To search in a specific repository, use the repository syntax:

soar search bat:official

Search Results Display

Search results use status icons:

IconMeaning
[+]Package is installed
[-]Package is not installed
[?]Installation status unknown

Example output:

[+] bat#official:official (0.24.0)
[-] bat#official:bincache (0.23.0)
[?] code#official:flathub (latest)

Query Command

The query command provides detailed package information:

soar query <package>

# Using shorter aliases
soar Q <package>

Example: Get detailed information about a package

soar query bat

Query Syntax

The query command supports detailed syntax for specific lookups:

soar query <name>#<pkg_id>@<version>:<repo>

Format breakdown:

  • <name> - Package name (required)
  • #<pkg_id> - Package ID (optional, for disambiguation)
  • @<version> - Version constraint (optional)
  • :<repo> - Repository name (optional)

Query Output Format

The query command returns information in this format:

FieldDescription
NamePackage name
VersionCurrent/latest version
RepositorySource repository
pkg_idPackage ID/family
Status[installed], [not-installed], or [broken]
SizePackage size on disk
Install DateWhen the package was installed
Last UpdatedLast update timestamp
ProvidesAlternative binary names
DescriptionPackage description

Example Query Output

soar query bat

Output:
Name:        bat
Version:     0.24.0
Repository:  official
pkg_id:      catlike.tools.bat.official
Status:      [installed]
Size:        2.3 MiB
Install Date: 2025-01-15
Last Updated: 2025-01-20
Provides:    batcat
Description: A cat clone with syntax highlighting and Git integration

Search Patterns

Partial Matching

Matches any package containing the query string:

# Matches any package containing "fire"
soar search fire

# Matches any package containing "code"
soar search code

Example results for soar search fire:

[-] firefox#mozilla:official (122.0)
[-] firewall#system:official (latest)
[+] firefoxpwa#third-party:flathub (1.0)

pkg_id Searching

Search by package ID family:

# Search in pkg_id
soar search git.busybox.net

Provides Searching

Search by alternative binary names:

# Find packages that provide alternative names
soar search batcat

This finds bat because it provides batcat as an alternative name.

Tips for Effective Searching

  1. Start Simple: Begin with simple queries before adding filters

    soar search editor
    
  2. Use Case Sensitivity: For disambiguation between similar names

    soar search Bat --case-sensitive
    
  3. Combine with Query: Use query for detailed information after searching

    soar search bat
    soar query bat
    
  4. Limit Results: For popular terms, limit results for clarity

    soar search tool --limit 10
    
  5. Check Alternative Names: Search for known aliases (provides)

    soar search batcat
    
  6. Repository Specific: If you know the repository

    soar search bat:official
    

Configuration

Search behavior can be configured in Soar’s configuration file. See Configuration for details on:

  • Default search repositories
  • Search result ordering
  • Case sensitivity defaults
  • Result limit defaults

List Packages

Soar provides commands to list available and installed packages. This guide covers all listing operations and features.

List vs Info: What’s the Difference?

Before diving into the commands, it’s important to understand the distinction:

  • soar list: Lists available packages from repositories (what you can install)
  • soar info: Lists installed packages on your system (what you have installed)

List Available Packages

The list command shows all packages available across your configured repositories.

Basic Usage

# List all available packages
soar list

# Using the short alias
soar ls

Filter by Repository

To list packages from a specific repository only:

# List packages from the 'bincache' repository
soar list bincache

# List packages from the 'myrepo' repository
soar ls myrepo

Example Output

$ soar list bincache

[-] 7z#e4d8:bincache | 24.09 | archive
[+] bat#7a3c:bincache | 0.24.0 | cli
[+] curl#9f2d:bincache | 8.11.1 | web
[-] ffmpeg#1b5e:bincache | 7.1 | multimedia
...

┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Total     ┃ 4            ┃
┃ ━━━━━━━━━━━━━━━━━━━━━━━┃
┃ ✓ Installed ┃ 2            ┃
┃ ▸ Available ┃ 2            ┃
┗━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛

Output Format: [icon] name#pkg_id:repo | version | type

  • Icon: + (green) or ✓ = installed, - or ▸ = available, ? = unknown status
  • name: Package name (blue)
  • pkg_id: Package identifier (cyan)
  • repo: Repository name (cyan)
  • version: Package version (light red)
  • type: Package type (magenta, optional)

List Installed Packages

The info command (aliased as list-installed) shows all packages currently installed on your system, including their size and installation status.

Basic Usage

# List all installed packages
soar info

# Using the list-installed alias
soar list-installed

It will list all the installed packages alongside the total size used by each package. This will also report partially installed packages as Broken.

Info Command Options

OptionShortDescription
--repo-name-rFilter installed packages by repository name
--count-Only show the total count of unique installed packages

Filter Installed Packages by Repository

To see only packages installed from a specific repository:

# Show packages installed from 'bincache'
soar info --repo-name bincache

# Using the short option
soar info -r bincache

Count Installed Packages

To get a quick count of installed packages:

# Show total count of unique packages
soar info --count

# Count packages from specific repository
soar info --repo-name bincache --count

Example Output

$ soar info

bat-0.24.0:bincache (2025-01-15) (1.8 MB)
curl-8.11.1:bincache (2025-01-15) (2.4 MB)
ffmpeg-7.1:bincache (2025-01-14) (15.2 MB)
jq-1.7.1:bincache (2025-01-10) (1.5 MB) ✗ Broken

┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ✓ Installed ┃ 3, 3 distinct (20.0 MB)     ┃
┃ ✗ Broken    ┃ 1 (1.5 MB)                  ┃
┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ Total       ┃ 4 (21.5 MB)                 ┃
┗━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Output Format: name-version:repo (date) (size) [status]

  • name: Package name (blue)
  • version: Package version (magenta)
  • repo: Repository name (cyan)
  • date: Installation date (green)
  • size: Package size on disk (human-readable)
  • status: Empty for installed packages, ✗ Broken or [Broken] (red) for packages with missing/corrupted files
$ soar info --count
4

Advanced Use Cases

Checking Package Status

Use info to verify installation status before performing operations:

# Check if package is installed
soar info | grep ripgrep

# Check specific repository packages
soar info --repo-name bincache | grep ffmpeg

Common Use Cases

Find What’s Available vs Installed

# See all available ffmpeg packages
soar list | grep ffmpeg

# Check if ffmpeg is installed
soar info | grep ffmpeg

Repository Management

# List all packages in a repository before adding it
soar list new-repo

# After installation, verify what was installed
soar info --repo-name new-repo

# Get quick count of packages from repository
soar info --repo-name new-repo --count

System Cleanup

# Check total packages installed
soar info --count

# Identify broken installations
soar info | grep "Broken"

# Remove broken packages (see remove.md)
soar remove broken-package

See Also

Use Package From Different Family

Soar allows you to switch between different variants of installed packages without uninstalling any. This feature is particularly useful when you need to switch between different versions, implementations, or repository sources of the same package.

Understanding Package Families

A package family refers to multiple installed variants of the same package name. These variants can differ in:

Variant TypeExampleDescription
Versionpython@3.11 vs python@3.12Different versions of the same package
Implementationcat (GNU) vs cat (BusyBox)Different implementations providing the same binary
Repositoryneovim from main vs testingSame package from different repositories
Package IDcoreutils vs coreutils-ucrDifferent package IDs providing similar functionality

Example Package Families

Package: python
├── python#python@3.11 (from main repo)
├── python#python@3.12 (from main repo)
└── python#pypy@3.11 (from testing repo)

Package: cat
├── cat#coreutils@9.5 (provides: cat, ls, etc.)
├── cat#busybox@1.36 (provides: cat, ls, etc.)
└── cat#uutils-coreutils@0.0.23 (provides: cat, ls, etc.)

When to Switch Packages

Common Use Cases

  1. Version Testing

    # Switch to Python 3.12 to test new features
    soar use python
    # Select python@3.12 from the list
    python --version
    
  2. Compatibility Requirements

    # Switch to older Node.js for a legacy project
    soar use node
    # Select node@18 from the list
    
  3. Alternative Implementations

    # Switch to BusyBox variants for embedded systems
    soar use cat
    # Select busybox@1.36 for smaller footprint
    
  4. Testing Repository Versions

    # Try a package from the testing repository
    soar use neovim
    # Select neovim from testing repo
    

How the Use Command Works

graph TD
    A["soar use python"] --> B{"Multiple variants
installed?"} B -->|"No"| C["Exit — nothing to switch"] B -->|"Yes"| D["Display installed variants"] D --> E["User selects variant"] E --> F["Overwrite primary binary symlink"] F --> G["Overwrite all provides symlinks
(cat, ls, chmod, etc.)"] G --> H["Mark selected variant active in DB"] H --> I["Mark other variants inactive"] style C fill:#1c2128,stroke:#8b949e,color:#e6edf3 style I fill:#1c2128,stroke:#3fb9a2,color:#e6edf3

Step 1: List Installed Variants

When you run soar use <package>, Soar displays all installed variants:

$ soar use python

[1] python#python:3.11.5-main (15MB) *
[2] python#python:3.12.0-main (16MB)
[3] python#pypy:3.11.0-testing (12MB)

Select a variant [1-3]:

Step 2: Select a Variant

Select the number corresponding to your desired variant. Soar will then:

  1. Overwrite symlinks for the package and its provides entries (existing symlinks are replaced, not removed separately)
  2. Mark the selected variant as active in the database
  3. Mark other variants as inactive (they remain installed but unlinked)

Step 3: Verify the Switch

$ python --version
Python 3.12.0

Command Syntax

soar use <package_name>
  • <package_name>: The base package name only (e.g., python, cat, node)
    • Do not use version suffixes (e.g., use python, not python@3.12)
    • Do not use pkg_id prefixes (e.g., use python, not python#pypy)
  • No additional flags or options are supported
  • The command is interactive when multiple variants are installed
  • Early exit: If only one variant is installed, the command exits without prompting (nothing to switch)

What Gets Switched

When you switch packages, Soar manages:

Primary Binary

The main binary name:

# Switching 'python' affects:
~/.local/share/soar/bin/python -> /path/to/python@3.12/bin/python

Provided Binaries

All binaries listed in the package’s provides field:

# Switching 'coreutils' affects all its provides:
~/.local/share/soar/bin/cat -> /path/to/coreutils/bin/cat
~/.local/share/soar/bin/ls -> /path/to/coreutils/bin/ls
~/.local/share/soar/bin/chmod -> /path/to/coreutils/bin/chmod
# ... and more

Warning: Switching a package affects ALL binaries it provides. If you switch coreutils, you’ll switch cat, ls, chmod, and all other core utilities simultaneously.

Practical Examples

Python Version Management

soar install python@3.11 python@3.12
soar use python  # Select python@3.12
python --version  # Python 3.12.0

Alternative Implementations

soar install coreutils uutils-coreutils
soar use cat  # Select uutils-coreutils
ls --version  # uutils-coreutils 0.0.23

Managing Multiple Variants

Viewing All Installed Variants

To see all installed packages and their variants:

soar info

# Output:
# Installed packages:
# python@3.11.5 (main)
# python@3.12.0 (main)
# node@18.0.0 (main)
# node@20.0.0 (main)
# coreutils@9.5 (main)
# busybox@1.36 (main)

Removing Unwanted Variants

If you no longer need a variant:

# Remove a specific variant
soar remove python@3.11

# Remove all variants
soar remove --all python

Limitations and Considerations

1. Must Be Installed First

You can only switch between installed variants. If no variants are installed:

$ soar use python
Package is not installed

The command displays this message and exits gracefully (no error code).

2. No Automatic Rollback

There’s no automatic undo. You must manually switch back:

soar use python
# Select different variant

3. Affects All Provides

Switching affects all binaries the package provides:

soar use coreutils
# This switches cat, ls, chmod, mkdir, etc. all at once

Best Practices

  • Install Multiple Versions: Install all versions you might need for development
  • Document Requirements: Note required versions in project README
  • Use Profiles: Use different profiles for different project requirements
  • Test First: Use soar run to test before switching in production

Comparison with Other Tools

Featuresoar useupdate-alternativesnvmpyenv
Multiple Versions
Package Agnostic
Repository Support

Troubleshooting

Issue: Command not found after switch

soar use python
python: command not found

Solution: This error means Soar’s bin directory is not in your PATH. Add it permanently:

# Add to your ~/.bashrc, ~/.zshrc, or equivalent
export PATH="$HOME/.local/share/soar/bin:$PATH"

Then reload your shell:

source ~/.bashrc  # or source ~/.zshrc

Issue: Old version still showing

soar use python
python --version  # Still shows old version

Solution: Check for cached paths:

hash -r  # Clear command hash table
python --version  # Should show new version

Issue: No variants listed

If you don’t see any variants listed when running soar use:

$ soar use python
Package is not installed

Solution: Install at least one variant of the package first:

soar install python
soar use python  # Now shows installed variants

Run Packages

Soar allows you to run packages without installing them permanently on your system. While the package files are still downloaded and stored, they aren’t integrated into your system PATH or desktop environment. This feature is perfect for trying out applications or running one-off tasks.

Run vs Install

Featuresoar runsoar install
PATH Integration❌ Not added to PATH✅ Added to profile’s bin directory
Desktop Integration❌ No desktop entries✅ Desktop entries created
Persistence✅ Files stored for reuse✅ Permanently installed
Symlinks❌ No symlinks created✅ Symlinks for provides entries
Quick AccessMust use full commandAvailable from anywhere
CleanupManual removal from cache directoryManaged via soar remove
Use CaseTry before installing, one-off tasksDaily use applications

Note: When to use run: Testing a new tool, running a security scanner occasionally, trying different versions, or when you don’t want to clutter your PATH.

Basic Usage

The basic syntax for running a package:

soar run <package> [command arguments...]

The first argument after run is the package name, followed by any arguments to pass to the package’s binary.

Example: Run feroxbuster

soar run feroxbuster --url https://example.com --depth 2

Example: Run a specific version

soar run python@3.11 --version

Command Options

The run command supports several options to control package selection and behavior:

--yes / -y

Skip all prompts and automatically select the first available package variant.

soar run --yes feroxbuster

This is useful for scripting or when you’re confident in the default selection.

--pkg-id <ID>

Specify the exact package ID to run. This is useful when multiple packages provide the same binary.

soar run --pkg-id coreutils@9.5 ls --version

--repo-name <REPO> / -r <REPO>

Specify which repository to fetch the package from.

soar run --repo-name main python

This is helpful when the same package exists in multiple repositories.

Command Passing

Any arguments after the package name are passed directly to the package’s binary:

soar run feroxbuster --url https://example.com --depth 2 --threads 10

In this example:

  • feroxbuster is the package name
  • --url https://example.com --depth 2 --threads 10 are arguments passed to feroxbuster

Warning: The first non-option argument is treated as the package name. All subsequent arguments are passed to the package.

Example: Running with complex arguments

soar run python -c "print('Hello from Soar!')"
soar run node --eval "console.log('Node.js via Soar')"

Storage and Caching

Soar caches run packages in ~/.local/share/soar/cache/bin to avoid re-downloading:

  • Downloads once: Package is downloaded on first run
  • Reuses cached binary: Subsequent runs use the cached copy
  • Checksum validation: Validates checksums after download; prompts for confirmation on mismatch
  • Separate from installed packages: Uses cache directory, not the packages directory

Info: Cached binaries persist for faster subsequent execution. Clean them manually from ~/.local/share/soar/cache/bin or use soar clean --cache when no longer needed.

Practical Examples

Try before you install

# Test a network scanner
soar run feroxbuster --help

# If you like it, install it permanently
soar install feroxbuster

Run specific versions

# Run Python 3.11 for a specific script
soar run python@3.11 script.py

# Run Node.js 20 for a project
soar run node@20 --version

Run from a specific repository

# Run from the 'testing' repository
soar run --repo-name testing experimental-tool

# Run with a specific package ID
soar run --pkg-id neovim@0.10.1 nvim --version

One-off tasks

# Run a security audit without installing tools permanently
soar run semgrep --config auto /path/to/code

# Process a file with a specialized tool
soar run jq '.filter | map(select(.value > 10))' data.json

Scripting with –yes

#!/bin/bash
# Automated security scan
soar run --yes feroxbuster --url "$TARGET" --output scan-results.txt
soar run --yes nuclei -u "$TARGET" -severity critical

Cleanup

Run packages are stored in the cache directory and are not tracked in the installed packages database. To remove them:

# Clean all cached run packages
soar clean --cache

# Or manually remove specific packages from cache directory
rm ~/.local/share/soar/cache/bin/<package-name>

Warning: Run packages are not tracked by soar remove. Use soar clean --cache to remove cached run packages, or delete them manually from ~/.local/share/soar/cache/bin.

Tips and Best Practices

  1. Use --yes in scripts to avoid interactive prompts
  2. Specify --pkg-id when you need exact version control
  3. Use --repo-name to select packages from specific repositories
  4. Pass --help to see package-specific options: soar run package --help
  5. Combine with shell features for powerful one-liners

Pro tip: Create shell aliases for frequently-run packages:

alias py311='soar run python@3.11'
alias node20='soar run node@20'

Inspect Packages

Soar provides powerful inspection commands to help you understand packages before installation and debug issues after installation. This guide covers the inspect, log, and query commands.

Overview of Inspection Commands

Soar offers three complementary inspection commands:

CommandPurposeUse When
soar queryView detailed package metadataYou want comprehensive package information
soar inspectView build scriptsYou need to understand how a package is built
soar logView build logsYou’re debugging installation failures

Query Command

The query command provides detailed metadata about packages, including versions, sizes, dependencies, and repository information.

Basic Usage

# Query a package by name
soar query <package>

# Using the short alias
soar Q <package>

How Query Works

The query command searches for packages and displays detailed information in a formatted table. It checks:

  • Package name
  • Package ID (pkg_id)
  • Version numbers
  • Repository sources

Examples

$ soar query bat

✓ Name            bat#cat:bincache
✓ Description     A cat(1) clone with wings
✓ Version         0.24.0
✓ Size            1.8 MB
✓ Checksum        abc123... (blake3)
✓ Type            binary

Query Output Format

The query command displays the following information:

FieldDescription
NamePackage name in format name#pkg_id:repo
DescriptionHuman-readable package description
VersionCurrent package version
SizeDownload size (formatted for readability)
ChecksumBLAKE3 checksum for download verification
HomepagesOfficial project websites
LicensesPackage license information
MaintainersPackage maintainer contact information
NotesAdditional installation or usage notes
TypePackage type (appimage, flatimage, archive, etc.)
Build CIBuild action and build ID
Build DateWhen the package was built
Build LogLink to build log output
Build ScriptLink to build script used
GHCR BlobGitHub Container Registry blob URL (if available)
Download URLDirect download URL (shown if GHCR Blob not available)
GHCR PackageFull GHCR package URL
IndexPackage index page URL

Note: Some fields are optional and may not appear if not available for the package. The download information shows either GHCR Blob or Download URL depending on the package source.

Use Cases

  • Before Installation: Verify package details before installing
  • Version Comparison: Check what versions are available
  • Repository Verification: Confirm which repository provides a package
  • Size Planning: Check package size for disk space planning

Inspect Command

The inspect command displays the build script (SBUILD) used to compile or prepare a package. This helps you understand:

  • Build dependencies
  • Compilation commands
  • Installation steps
  • Custom build logic

Basic Usage

# View build script for a package
soar inspect <package>

How Inspect Works

The inspect command:

  1. Searches for matching packages (by name, pkg_id, or version)
  2. If multiple matches found, prompts for interactive selection
  3. Checks if package is installed locally - reads from $INSTALL_DIR/SBUILD
  4. If not installed locally, fetches from repository URL
  5. Displays the complete build script

Examples

$ soar inspect ffmpeg

Reading build script from /home/user/.local/share/soar/packages/ffmpeg-7.1 [15.2 MB]

# SBUILD file for ffmpeg
pkg_name="ffmpeg"
pkg_version="7.1"
pkg_source="https://ffmpeg.org/releases/ffmpeg-7.1.tar.xz"

build() {
    ./configure --prefix="$INSTALL_DIR" --enable-gpl
    make -j$(nproc)
    make install
}

dependencies=["nasm", "pkg-config", "libx264-dev"]

Inspect Output Format

Build scripts follow the SBUILD format with these common sections:

SectionDescription
pkg_namePackage name
pkg_versionVersion string
pkg_sourceDownload URL or source location
build()Build commands (compilation, installation)
dependenciesBuild dependencies required

Interpreting Build Scripts

Understanding Build Commands

build() {
    # Configure step - sets up build configuration
    ./configure --prefix="$INSTALL_DIR" --enable-feature

    # Compile step - builds the software
    make -j$(nproc)

    # Install step - copies files to install directory
    make install
}

Environment Variables Available

Build scripts have access to these variables:

VariableDescription
$INSTALL_DIRTarget installation directory
$PKG_NAMEPackage name
$PKG_VERSIONPackage version
$NPROCNumber of CPU cores (for parallel builds)

Use Cases

  • Security Audit: Review what commands run during installation
  • Build Debugging: Understand why a package fails to build
  • Customization: See if you can modify build options
  • Dependency Planning: Check build dependencies before installing
  • Learning: Understand how packages are assembled

Log Command

The log command displays the build log from the last installation attempt. This is invaluable for debugging failed installations.

Basic Usage

# View build log for a package
soar log <package>

How Log Works

The log command:

  1. Searches for matching packages
  2. If multiple matches found, prompts for selection
  3. Checks if package is installed locally - reads from $INSTALL_DIR/<package>.log
  4. If not installed locally, fetches from repository URL
  5. Displays the complete build log

Examples

$ soar log bat

[2024-01-15 10:23:45] Starting installation of bat-0.24.0
[2024-01-15 10:23:47] Download complete: 1.8 MB
[2024-01-15 10:23:48] Installation completed successfully
$ soar log python@3.12

[2024-01-15 11:30:12] Starting installation of python@3.12
[2024-01-15 11:31:20] ERROR: Build failed
[2024-01-15 11:31:20] ERROR: openssl/ssl.h: No such file or directory

View Failed Installation Log

$ soar log python@3.12

Reading build log from /home/user/.local/share/soar/packages/python@3.12 [25.4 MB]

[2024-01-15 11:30:12] Starting installation of python@3.12
[2024-01-15 11:30:12] Downloading from https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz
[2024-01-15 11:30:45] Download complete: 25.4 MB
[2024-01-15 11:30:45] Extracting to /tmp/python@3.12
[2024-01-15 11:30:47] Running build commands from SBUILD
[2024-01-15 11:30:48] Executing: ./configure --prefix="$INSTALL_DIR"
...
[2024-01-15 11:31:20] ERROR: Build failed
[2024-01-15 11:31:20] ERROR: openssl/ssl.h: No such file or directory
[2024-01-15 11:31:20] ERROR: Build dependency 'openssl-dev' not found
[2024-01-15 11:31:20] Installation failed

View Log for Specific Version

# Check log for a specific version
soar log "ripgrep@13.0"

Log Output Format

Build logs contain timestamped entries for each installation step:

Timestamp FormatExample
Start/End markers[2024-01-15 10:23:45] Starting installation...
Progress updates[2024-01-15 10:23:47] Download complete: 1.8 MB
Success messages[2024-01-15 10:23:48] Installation completed successfully
Error messages[2024-01-15 11:31:20] ERROR: Build failed

Interpreting Build Logs

Common Success Patterns

[timestamp] Starting installation of <package>-<version>
[timestamp] Downloading from <url>
[timestamp] Download complete: <size>
[timestamp] Verifying checksum... OK
[timestamp] Extracting to <temp_dir>
[timestamp] Running build commands from SBUILD
[timestamp] Installation completed successfully

Common Failure Patterns

# Missing build dependency
[timestamp] ERROR: <header_file>: No such file or directory
[timestamp] ERROR: Build dependency '<dep>' not found

# Download failure
[timestamp] ERROR: Failed to download from <url>
[timestamp] ERROR: HTTP 404 Not Found

# Checksum mismatch
[timestamp] ERROR: Checksum verification failed
[timestamp] ERROR: Expected <hash1>, got <hash2>

# Build command failure
[timestamp] ERROR: Build failed with exit code 1
[timestamp] ERROR: make: *** No rule to make target 'install'

Use Cases

  • Debug Failures: Understand why an installation failed
  • Verify Installation: Confirm all steps completed successfully
  • Performance Analysis: Check how long installation took
  • Audit Trail: Review what happened during installation
  • Bug Reports: Include logs when reporting issues

Package Query Syntax

All three inspection commands support a flexible package query syntax:

Query Formats

# By name only
soar query bat

# By package ID (includes version variants)
soar query python@3.12

# By specific version
soar query "ripgrep@14.0"

# By repository (using colon syntax)
soar query bat:bincache

Query Components

ComponentFormatExampleDescription
NamepackagebatPackage name
Package IDpackage@versionpython@3.12Specific variant
Versionpackage@versionripgrep@14.0Exact version
Repositorypackage:repobat:bincacheSource repository

Interactive Selection

When multiple packages match your query, Soar prompts for selection:

$ soar query python

Multiple packages found. Select one:
  1) python@3.12 (bincache) - Python 3.12.1
  2) python@3.11 (bincache) - Python 3.11.8
  3) python@3.10 (bincache) - Python 3.10.13

Enter selection [1-3]: 1

Common Workflows

Pre-Installation Investigation

soar query bat
soar inspect bat
soar info | grep bat

Debugging Failed Installations

soar log python@3.12
soar inspect python@3.12
soar install python@3.12 -vv

Comparing Package Versions

soar query "ripgrep@13.0"
soar query "ripgrep@14.0"
soar inspect "ripgrep@13.0"

Tips

  • Use soar query before installing to verify package details
  • Check build scripts before installing to understand dependencies
  • Always check the build log first when troubleshooting
  • Search for errors with grep ERROR on log files

Troubleshooting

No Build Script/Log Found

Binary packages don’t have build scripts. Build logs only exist after installation attempt.

Query Returns Multiple Matches

Use more specific query: soar query python@3.12 or specify repository: soar query python:bincache

Large Files Prompt for Confirmation

Files over 1 MB require confirmation. Use less for pagination or save to file.

For more help, see Health Check

See Also

Download Files

This section covers Soar’s powerful download capabilities.

Soar provides powerful download capabilities with support for direct URLs, GitHub releases, GitLab releases, and GitHub Container Registry (GHCR). The download command includes advanced filtering to narrow down options, interactive asset selection when multiple matches remain, and automatic archive extraction.

Basic Usage

To download a file, use the download command or the dl alias:

soar download <url>

Example: Download Soar nightly

soar download https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-x86_64-linux

To set the output filename or directory, use the --output or -o flag:

soar download https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-x86_64-linux -o soar-nightly

Example: Download multiple files and save them to the downloads directory

soar download https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-x86_64-linux https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-aarch64-linux -o downloads/

Warning: It currently doesn’t support multiple custom output filenames. So if you specify an output filename, it will be used for all downloads, meaning only the last download will be saved if you specify multiple URLs.

Package Downloads

Download packages directly from configured Soar repositories:

# Download by package name
soar download neovim

# Download specific version
soar download neovim@0.9.5

# Download from specific repo
soar download repo/neovim

Download Command Options

Confirmation Options

OptionShortDescription
--yes-ySkip confirmation prompts (useful for scripts)

Output Options

OptionShortDescription
--output-oSet output filename or directory

Filtering and Selection Options

OptionShortDescription
--regex-rFilter assets using regular expression pattern (works with all sources)
--glob-gFilter assets using glob pattern (works with all sources)
--match-Filter assets by keyword substring matching (works with all sources)
--exclude-Exclude assets matching this pattern (works with all sources)
--exact-case-Enable case-sensitive matching (default is case-insensitive)

Filter Behavior: Filters narrow down the available assets. If multiple assets remain after filtering, Soar shows an interactive selection prompt for you to choose manually. Use --yes to skip the prompt and automatically download the first matching asset.

Source Options

OptionDescription
--githubDownload from GitHub releases using format owner/repo[@tag]
--gitlabDownload from GitLab releases using format owner/project[@tag]
--ghcrDownload from GitHub Container Registry using format owner/image[:tag]

Extraction Options

OptionDescription
--extractAutomatically extract downloaded archives (supports .tar, .tar.gz, .tar.xz, .tar.zst, .zip)
--extract-dirCustom extraction directory (default: current directory or output path)

File Handling Options

OptionDescription
--skip-existingSkip download if file already exists
--force-overwriteOverwrite existing files without prompting

Download Sources

Direct URLs

Download any file from the internet using direct URLs:

# Single file
soar download https://example.com/file.tar.gz

# Save to specific location
soar download https://example.com/file.tar.gz -o /path/to/download/

# With automatic extraction
soar download https://example.com/file.tar.gz --extract

URL Auto-Detection: Soar automatically detects GitHub/GitLab/GHCR URLs. You don’t need --github/--gitlab/--ghcr flags when using full URLs.

GitHub Releases

Download assets from GitHub releases using the --github flag:

# Basic format: owner/repo
soar download --github pkgforge/soar

# Specific tag/release
soar download --github pkgforge/soar@v1.0.0

# Filter by architecture using regex
# Shows interactive selection if multiple assets match 'x86_64-linux'
soar download --github pkgforge/soar --regex 'x86_64-linux'

# Filter by multiple patterns
# Shows interactive selection if both x86_64 and aarch64 matches exist
soar download --github pkgforge/soar --regex 'x86_64-linux|aarch64-linux'

# Use --yes to skip interactive selection and download first match
soar download --github pkgforge/soar --regex 'x86_64-linux' --yes

# Download and extract automatically
soar download --github pkgforge/soar@nightly --regex 'x86_64-linux' --extract

# Exclude certain assets
soar download --github pkgforge/soar --exclude 'musl' --exclude 'debug'

Latest Release Behavior: Without a tag or with @latest, Soar downloads the latest stable release (skips prereleases). Use @tag-name for specific versions including prereleases.

GitHub Asset Selection Examples

# Download only musl builds
# Interactive: shows all musl builds if multiple match
soar download --github cli/cli --glob '*-musl*'

# Download only .tar.gz files
# Interactive: shows all .tar.gz files if multiple match
soar download --github pkgforge/soar --glob '*.tar.gz'

# Match specific keywords
# Interactive: shows all assets containing 'appimage' if multiple match
soar download --github neovim/neovim --match 'appimage'

# Auto-download first match (skip interactive selection)
soar download --github cli/cli --glob '*-musl*' --yes

# Case-sensitive matching
soar download --github pkgforge/soar --exact-case --regex 'Linux'

GitLab Releases

Download assets from GitLab releases using the --gitlab flag:

# Basic format: owner/project
soar download --gitlab gitlab-org/gitlab

# Specific tag/release
soar download --gitlab gitlab-org/gitlab@v16.0.0

# Filter by platform
soar download --gitlab gitlab-org/gitlab --regex 'linux-amd64'

# Download and extract
soar download --gitlab gitlab-org/gitlab@v16.0.0 --regex 'linux-amd64' --extract

Latest Release Behavior: Without a tag or with @latest, Soar downloads the latest stable release (skips prereleases). Use @tag-name for specific versions including prereleases.

GitLab Asset Selection Examples

# Download only ARM64 builds
# Interactive: shows all ARM64 builds if multiple match
soar download --gitlab gitlab-org/gitlab --glob '*-arm64*'

# Download specific file types
# Interactive: shows all .tar.xz files if multiple match
soar download --gitlab gitlab-org/gitlab --glob '*.tar.xz'

# Auto-download first match (skip interactive selection)
soar download --gitlab gitlab-org/gitlab --glob '*-arm64*' --yes

# Exclude debug builds
soar download --gitlab gitlab-org/gitlab --exclude 'debug'

GitHub Container Registry (GHCR)

Download container images from GitHub Container Registry:

# Basic format: owner/image
soar download --ghcr pkgforge/soar

# Specific tag
soar download --ghcr pkgforge/soar:latest

# Specific version
soar download --ghcr pkgforge/soar:v1.0.0

# Multiple tags
soar download --ghcr pkgforge/soar:alpine --ghcr pkgforge/soar:slim

Automatic Retry: GHCR downloads automatically retry on rate limits (HTTP 429) or network errors (up to 5 attempts with 5-second delays).


Asset Selection Patterns

How Asset Selection Works

Soar’s filtering works in two stages:

  1. Filtering Stage: Filters (--regex, --glob, --match, --exclude) narrow down the list of available assets
  2. Selection Stage:
    • If exactly one asset matches → automatically downloaded
    • If multiple assets match and --yes is NOT set → interactive selection prompt appears
    • If multiple assets match and --yes IS set → first matching asset is automatically downloaded

Key Point: Filters reduce the options but don’t automatically select which file to download when multiple matches remain. The user must choose interactively unless --yes is specified.

Pattern Matching Options

Soar provides three ways to filter assets:

  1. Regex (--regex / -r): Full regular expression support
  2. Glob (--glob / -g): Shell-style glob patterns
  3. Match (--match): Simple substring matching

Regex Examples

# Match specific architecture
# Auto-downloads if exactly one match, otherwise shows selection
soar download --github pkgforge/soar --regex 'x86_64-unknown-linux-gnu'

# Match multiple architectures
# Interactive: shows both x86_64 and aarch64 if both exist
soar download --github pkgforge/soar --regex '(x86_64|aarch64)-linux'

# Match version patterns
soar download --github pkgforge/soar --regex 'v[0-9]+\.[0-9]+\.[0-9]+'

# Match file extensions
# Interactive: shows all .tar.gz and .zip files if multiple match
soar download --github pkgforge/soar --regex '\.(tar\.gz|zip)$'

Glob Examples

# Match all Linux builds
# Interactive: shows all Linux builds if multiple match
soar download --github pkgforge/soar --glob '*linux*'

# Match specific file type
soar download --github pkgforge/soar --glob '*.tar.gz'

# Match architecture pattern
soar download --github pkgforge/soar --glob '*-x86_64-*'

# Match AppImages
# Auto-downloads if only one AppImage exists
soar download --github neovim/neovim --glob '*.AppImage'

Keyword Match Examples

# Find assets containing "linux"
# Interactive: shows all assets with "linux" if multiple match
soar download --github pkgforge/soar --match linux

# Find assets containing "musl"
soar download --github pkgforge/soar --match musl

# Multiple keywords (AND logic - all must match)
# Narrows down to assets containing both "linux" AND "x86_64"
soar download --github pkgforge/soar --match linux --match x86_64

Exclusion Patterns

Use --exclude to filter out unwanted assets. Combined with other filters, this narrows down the selection pool. If multiple assets remain after exclusions, interactive selection is shown:

# Exclude musl builds
# Shows selection of non-musl builds if multiple remain
soar download --github pkgforge/soar --exclude 'musl'

# Exclude debug builds
soar download --github pkgforge/soar --exclude 'debug'

# Multiple exclusions
soar download --github pkgforge/soar --exclude 'musl' --exclude 'debug' --exclude 'test'

# Combine with inclusion patterns
# Shows Linux builds excluding musl (interactive if multiple match)
soar download --github pkgforge/soar --regex 'linux' --exclude 'musl'

Case Sensitivity

By default, pattern matching is case-insensitive. Use --exact-case for case-sensitive matching:

# Case-insensitive (default) - matches Linux, LINUX, linux
soar download --github pkgforge/soar --match linux

# Case-sensitive - only matches lowercase "linux"
soar download --github pkgforge/soar --match linux --exact-case

# Case-sensitive regex
soar download --github pkgforge/soar --regex '[A-Z]{2}' --exact-case

Archive Extraction

Soar can automatically extract downloaded archives:

Supported Formats

  • .tar
  • .tar.gz / .tgz
  • .tar.xz / .txz
  • .tar.zst / .tzst
  • .zip

Extraction Examples

# Extract to current directory
soar download https://example.com/file.tar.gz --extract

# Extract to specific directory
soar download https://example.com/file.tar.gz --extract --extract-dir /opt/app

# Download GitHub release and extract
soar download --github pkgforge/soar@v1.0.0 --regex 'x86_64-linux' --extract

# Extract with custom output
soar download https://example.com/file.tar.gz -o myfile.tar.gz --extract --extract-dir ./mydir

File Handling

Skip Existing Files

Avoid re-downloading files that already exist:

# Skip if file exists (default behavior)
soar download https://example.com/file.tar.gz --skip-existing

# Useful for batch downloads
soar download --github pkgforge/soar --regex 'linux' --skip-existing

Force Overwrite

Overwrite existing files without prompting:

# Force overwrite
soar download https://example.com/file.tar.gz --force-overwrite

# Combine with extraction
soar download https://example.com/file.tar.gz --extract --force-overwrite

Non-Interactive Mode

Skip all confirmation prompts with --yes. When multiple assets match your filters, --yes automatically downloads the first matching asset instead of showing an interactive selection:

# Download without confirmation
soar download https://example.com/file.tar.gz --yes

# Batch download with all options
# Skips interactive selection and downloads first match
soar download --github pkgforge/soar --regex 'linux' --extract --yes --skip-existing

# When multiple assets match, --yes picks the first one automatically
soar download --github cli/cli --regex 'linux' --yes

Interactive Selection

When multiple assets match your filters and --yes is not set, Soar displays an interactive selection prompt:

soar download --github cli/cli --regex 'linux'
# > Select an asset (1-4):
#   1. cli-linux-amd64.rpm (95.2 MB)
#   2. cli-linux-arm64.deb (89.1 MB)
#   3. cli-linux-386.tar.gz (91.5 MB)
#   4. cli-linux-amd64.tar.gz (95.2 MB)

The selection works as follows:

  • Exactly 1 match: Automatically downloads without prompting
  • Multiple matches + no --yes: Shows interactive prompt (as shown above)
  • Multiple matches + --yes: Automatically downloads the first matching asset

Automatic vs Interactive: Use filters to narrow down options. If only one asset remains after filtering, it downloads automatically. If multiple remain, you’ll be prompted to choose unless you use --yes to accept the first match.


Advanced Examples

Multi-Architecture Download

# Download multiple architectures
# Shows interactive selection if both x86_64 and aarch64 builds exist
soar download --github pkgforge/soar --regex '(x86_64|aarch64)-linux' -o ./binaries/

# Auto-download first architecture match
soar download --github pkgforge/soar --regex '(x86_64|aarch64)-linux' -o ./binaries/ --yes

Latest Release from Multiple Sources

# Download from GitHub
soar download --github pkgforge/soar@latest --regex 'linux' --extract

# Download from GitLab
soar download --gitlab gitlab-org/gitlab@latest --regex 'amd64' --extract

Filter and Extract Workflow

# Download, filter, and extract in one command
soar download --github neovim/neovim \
  --glob 'nvim-linux64.tar.gz' \
  --extract \
  --extract-dir ./nvim \
  --output nvim.tar.gz

Batch Downloads with Exclusions

# Download all Linux builds except musl
# Shows interactive selection if multiple non-musl Linux builds remain
soar download --github pkgforge/soar \
  --regex 'linux' \
  --exclude 'musl' \
  --exclude 'debug' \
  -o ./builds/

# Auto-download first match
soar download --github pkgforge/soar \
  --regex 'linux' \
  --exclude 'musl' \
  --exclude 'debug' \
  -o ./builds/ \
  --yes

Container Image Management

# Pull multiple image variants
soar download --ghcr pkgforge/soar:alpine
soar download --ghcr pkgforge/soar:slim
soar download --ghcr pkgforge/soar:latest

Tips and Best Practices

  1. Use --glob for simple patterns: Easier to read than regex for common cases
  2. Combine filters: Use both inclusion (--regex/--glob) and exclusion (--exclude) for precise control
  3. Understand selection behavior: Filters narrow down options, but if multiple assets remain, you’ll be prompted to choose (or use --yes for automatic first-match download)
  4. Test patterns first: Use --yes only after verifying your filters work correctly
  5. Extraction paths: Use --extract-dir to keep downloads organized
  6. Batch operations: --skip-existing is essential for re-running download scripts
  7. Case sensitivity: Most patterns are case-insensitive by default; use --exact-case when needed
  8. Asset names: GitHub/GitLab asset names typically include architecture, OS, and file type
  9. Latest releases: Use @latest or omit the tag to get the newest stable release (prereleases are skipped)
  10. Filter universality: --regex, --glob, --match, and --exclude work with all sources (GitHub, GitLab, GHCR)
  11. URL auto-detection: Full URLs are automatically detected; no need for --github/--gitlab/--ghcr flags
  12. Package downloads: Can download packages directly by name from configured repositories

Health

Soar’s health check command is designed to quickly identify potential issues with your soar installation, missing binaries, broken packages, and broken symlinks.

Usage

To check Soar’s health, run:

soar health

Environment Variables

To view all Soar-related environment variables and their current values, run:

soar env

This command displays:

  • SOAR_CONFIG - Config file path
  • SOAR_BIN - Binary directory path
  • SOAR_DB - Database directory path
  • SOAR_CACHE - Cache directory path
  • SOAR_PACKAGES - Packages directory path
  • SOAR_REPOSITORIES - Repository directory path

These environment variables can be set to override Soar’s default paths and behavior. For example:

# Use a custom cache directory
export SOAR_CACHE="/tmp/soar-cache"
soar install neovim

# Switch to nightly builds
SOAR_NIGHTLY=1 soar self update

Functionality

When executed, this command:

  • Checks if the Soar binary path is included in the PATH environment variable
  • Lists broken packages (incomplete package installations)
  • Lists broken symlinks (dangling symlinks created by Soar that no longer point to valid files)
    • bin directory: Detects all broken symlinks
    • desktop/icons directories: Only detects broken symlinks with filenames ending in -soar suffix

Output

The health check displays results in a table format with status indicators for each category:

Status icons:

  • checkmark (green) - Item is healthy
  • cross (red) - Issues found
  • arrow - Indicates individual items in a list

Table categories:

  • PATH - Checks if Soar’s binary directory is in your PATH
  • Broken Packages - Lists incomplete package installations
  • Broken Symlinks - Lists dangling symlinks created by Soar

When issues are detected, suggested commands are provided to fix them.

Fixing Issues

  • Remove broken packages Run:
    soar clean --broken
    
  • Remove broken symlinks Run:
    soar clean --broken-symlinks
    
  • Clear package cache Run:
    soar clean --cache
    

Clean Command

The clean command performs various maintenance operations to keep your Soar installation clean and efficient.

Usage

soar clean [OPTIONS]

Options

OptionDescription
--cacheDeletes the entire cache directory (all cached package files)
--brokenRemoves packages marked as broken in the database (incomplete installations)
--broken-symlinksRemoves broken symlinks from bin, desktop, and icons directories

Behavior

If no flags are provided, ALL clean operations are performed (cache, broken packages, and broken symlinks).

Examples

# Run all clean operations (no flags = clean everything)
soar clean

# Clean only the cache
soar clean --cache

# Remove only broken packages
soar clean --broken

# Remove only broken symlinks
soar clean --broken-symlinks

# Run specific clean operations
soar clean --cache --broken

When to Use Clean Operations

  • After installation failures: If soar health reports broken packages
  • To free disk space: Clear the cache (deletes entire cache directory)
  • After manual file removal: Clean up broken symlinks pointing to deleted files
  • Before major updates: Clear cache to ensure fresh downloads
  • General maintenance: Run soar clean with no flags to perform all operations

Sync Command

The sync command updates repository metadata from remote sources, ensuring you have the latest package information.

Usage

soar sync

Or use aliases:

soar S      # Short alias
soar fetch  # Alternative name

Functionality

When executed, this command:

  • Fetches the latest package metadata from all enabled repositories
  • Updates the local database with new package versions
  • Respects per-repository sync_interval settings

Sync Behavior

Repositories can be configured with different sync intervals:

# In config.toml
[[repositories]]
name = "main"
url = "https://example.com/repo"
sync_interval = "3h"  # Sync every 3 hours (default)

Special sync_interval values:

  • "always" - Sync every time soar sync is run
  • "never" - Never sync automatically
  • "auto" - Use default 3-hour interval
  • "3h", "12h", "1d" - Custom duration strings

When to Sync

  • Before searching for new packages: Ensures you see the latest versions
  • After adding a new repository: Fetch initial metadata
  • Before updating packages: Get latest version information
  • Anytime: Run to update repository metadata

Example

# Sync all repositories
soar sync

# Output example:
Syncing repository 'main'...
Fetching metadata from https://example.com/repo...
Updated: 1427 packages available

Example Usage

$ soar health

Example Output (No Issues)

╭────────────────────────────────────────╮
│          System Health Check           │
├──────────────────┬─────────────────────┤
│ PATH             │ ✓ Configured        │
│ Broken Packages  │ ✓ None              │
│ Broken Symlinks  │ ✓ None              │
╰──────────────────┴─────────────────────╯

Example Output (With Issues)

╭────────────────────────────────────────╮
│          System Health Check           │
├──────────────────┬─────────────────────┤
│ PATH             │ ⚠ /path/to/bin not │
│                  │   in PATH           │
│ Broken Packages  │ ✗ 2 found          │
│ Broken Symlinks  │ ✗ 1 found          │
╰──────────────────┴─────────────────────╯

Broken packages:
  → cat#test: /home/user/.local/share/soar/packages/cat-test-q1235
  → ls#test: /home/user/.local/share/soar/packages/ls-test-q2345
Run soar clean --broken to remove

Broken symlinks:
  → /home/user/.local/bin/ls
Run soar clean --broken-symlinks to remove

Maintenance

This section covers essential features that are fundamental to Soar’s operation and maintenance.

Self Management

Soar provides commands to manage the package manager itself, including updating to newer versions and complete uninstallation.

Update Soar

soar self update

Updates Soar to the latest version by downloading pre-compiled binaries from GitHub releases.

You can control which release channel to use through environment variables:

  • SOAR_NIGHTLY=1 Switches to the nightly (development) channel
  • SOAR_RELEASE=1 Switches to the stable release channel

These environment variables take precedence over the currently installed channel. For example:

# Update within current channel
soar self update

# Switch to and update from nightly channel
SOAR_NIGHTLY=1 soar self update

# Switch to and update from stable channel
SOAR_RELEASE=1 soar self update

Uninstall Soar

soar self uninstall

Completely removes Soar from your system. This command will:

  • Remove the Soar binary from your system
  • Prompt for confirmation before proceeding
  • Preserve your configuration and packages by default
  • Offer options to remove user data if desired

Warning: This action is irreversible. Consider backing up your configuration (~/.config/soar/config.toml) and packages (~/.local/share/soar/packages) before uninstalling.

Uninstall Options

# Uninstall Soar but keep configuration and packages
soar self uninstall

# After uninstallation, manually remove data if desired:
rm -rf ~/.config/soar
rm -rf ~/.local/share/soar

Maintenance Best Practices

Regular Health Checks

Run health checks periodically to ensure your Soar installation is in good condition:

# Weekly health check
soar health

What to look for:

  • PATH status (add Soar’s binary directory to your PATH if not configured)
  • Broken packages (incomplete installations that should be cleaned up)
  • Broken symlinks (dangling symlinks from removed packages; note: only -soar suffixed files are detected in desktop/icons directories)

Cache Management

Package caches can grow large over time. Regular cleanup helps maintain disk space:

# Clean everything (cache, broken packages, broken symlinks)
soar clean

# Clean only the cache
soar clean --cache

# Check cache size before cleaning
du -sh ~/.local/share/soar/cache

Note: The --cache flag deletes the entire cache directory.

Recommended schedule:

  • Monthly: If you install packages frequently
  • Quarterly: For moderate usage
  • As needed: When disk space is low

Sync Repository Metadata

Keep your package metadata up-to-date to see the latest versions:

# Sync before searching or installing
soar sync

Recommended schedule:

  • Automatic: Let Soar sync based on repository sync_interval settings (default: 3 hours)
  • Manual: Before searching for new packages or running updates

Note: Repositories configured with sync_interval = "always" will sync every time soar sync is run.

Cleanup After Failed Installations

Failed installations can leave broken packages and symlinks:

# Check for issues
soar health

# Clean up if issues found
soar clean --broken
soar clean --broken-symlinks

When to run:

  • After any installation failure
  • After system crashes during installations
  • Before major system updates

Scheduling Recommendations

Automated Maintenance

Set up automated maintenance tasks using cron (Linux):

Weekly Health Check (cron)

# Add to crontab with: crontab -e
# Run every Sunday at 2 AM
0 2 * * 0 /usr/bin/soar health > /tmp/soar-health.log 2>&1

Monthly Cache Cleanup (cron)

# Add to crontab with: crontab -e
# Run on the 1st of every month at 3 AM
0 3 1 * * /usr/bin/soar clean --cache > /tmp/soar-clean.log 2>&1

Systemd Timer (Linux with systemd)

Create /etc/systemd/system/soar-health.service:

[Unit]
Description=Soar Health Check
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/soar health
Nice=19
IOSchedulingClass=idle

Create /etc/systemd/system/soar-health.timer:

[Unit]
Description=Weekly Soar Health Check
Requires=soar-health.service

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target

Enable the timer:

sudo systemctl enable --now soar-health.timer

Manual Maintenance Checklist

Perform these tasks manually every 1-3 months:

  1. Health Check

    soar health
    
    • Review any warnings or errors
    • Fix broken packages/symlinks if found
  2. Update Soar

    soar self update
    
    • Keep Soar itself up-to-date
    • Review changelog for new features
  3. Clean Cache

    soar clean --cache
    
    • Free up disk space
    • Ensure fresh downloads on next install
  4. Review Packages

    soar list-installed
    
    • Identify unused packages
    • Remove packages you no longer need
  5. Update Packages

    soar update
    
    • Keep installed packages current
    • Review changelogs for breaking changes

Maintenance Schedule Summary

TaskFrequencyCommandPurpose
Health CheckWeeklysoar healthIdentify issues early
Full CleanMonthlysoar cleanClean cache, broken packages, and symlinks
Sync MetadataAutomaticsoar syncGet latest package info
Update SoarQuarterlysoar self updateGet latest features
Broken CleanupAs neededsoar clean --broken --broken-symlinksFix failed installs
Full MaintenanceQuarterlyAll commands aboveComplete system checkup

Troubleshooting Maintenance Issues

Sync Failures

If soar sync fails:

  1. Check network connectivity
  2. Verify repository URLs in ~/.config/soar/config.toml
  3. Try syncing individual repositories
  4. Check if repository is temporarily unavailable

Cache Won’t Clear

If soar clean --cache doesn’t free space:

  1. Check if other processes are using cached files
  2. Manually remove cache directory: rm -rf ~/.local/share/soar/cache/*
  3. Verify Soar has write permissions

Persistent Broken Packages

If soar health continues reporting broken packages:

  1. Try reinstalling the broken package: soar install --force <package>
  2. If that fails, remove and reinstall: soar remove <package> && soar install <package>
  3. Check if the package version is available in your repositories
  4. Report the issue to the repository maintainer

Release Notes

This section contains release notes for Soar versions, documenting new features, breaking changes, and improvements.

  • Soar 0.11 — Nest removal, custom desktop paths, release notes on update
  • Soar 0.10 — GitHub/GitLab sources, build-from-source, hooks, Landlock sandboxing, system-wide installs

Soar 0.11

0.11.0

Soar 0.11 focuses on simplification and improved user experience, removing deprecated features and adding quality-of-life improvements.

Breaking Changes

Nest functionality removed: The nest feature has been removed. If you were using nests to manage custom repositories, migrate to the standard repository configuration in config.toml. See Configuration for details on adding custom repositories.

--external flag removed: The --external flag for soar defconfig has been removed. Previously this flag enabled non-core repositories in the generated config. Now, no external repositories are provided by default, so you’d need to add them manually in your config.

Custom Desktop File Path

You can now configure where desktop files are installed. By default, Soar places .desktop files in ~/.local/share/applications (user mode) or /usr/local/share/applications (system mode). If you need them elsewhere, set the desktop_path field in your config:

desktop_path = "/path/to/custom/applications"

Alternatively, use the SOAR_DESKTOP environment variable.

Release Notes on Update

When updating Soar itself, you’ll now see release notes for the new version. This helps you stay informed about new features, breaking changes, and bug fixes without having to check the documentation manually.

The update experience has also been improved with clearer progress indicators and status messages.

Bug Fixes

  • Fixed detection of default repositories when no config file exists

Soar 0.10

0.10.3

Glob Support in Binary Maps

The source field in binary mappings now supports glob patterns, making it easier to select binaries from packages that contain multiple files:

[packages]
my-tools = {
  url = "https://example.com/tools.tar.gz",
  binaries = [
    { source = "bin/tool-*" }
  ]
}

When a glob matches multiple files, each matched file is symlinked using its original filename. The link_as field is now optional — if omitted, the symlink uses the source filename. When a glob matches a single file, link_as is used if specified.

Placeholder Support

URL and path fields now support {arch}, {os}, and {version} placeholders that are automatically substituted with system metadata:

[packages]
tool = {
  url = "https://example.com/tool-{version}-{arch}-{os}.tar.gz",
  version = "1.2.0"
}

Removal of update Field

The update field has been removed from packages.toml. GitHub and GitLab sources are now detected automatically from the github/gitlab fields, making the separate update configuration unnecessary.

Fallback Token Environment Variables

GitHub and GitLab token detection now supports fallback environment variables:

  • GitHub: GITHUB_TOKEN or GH_TOKEN
  • GitLab: GITLAB_TOKEN or GL_TOKEN

This improves compatibility with the GitHub CLI (gh) and other tools that use GH_TOKEN.

Bug Fixes

  • Fixed HTTP status code handling in download fallback logic
  • Install script now automatically uses system-wide mode (--system) when run as root

0.10.2

Changes

  • System install path changed from /usr/lib/soar to /opt/soar for compatibility with atomic/immutable distros

0.10.1

Bug Fixes

  • Fixed sudo privilege escalation failing to find soar binary when installed in user directories not in sudo’s secure_path

0.10.0

Soar 0.10 brings GitHub/GitLab release support, build-from-source, install hooks, Landlock sandboxing, and system-wide installs. This release addresses some of the most requested features and lays the groundwork for more flexible package management.

Breaking Changes

Before upgrading, note the following:

Database schema change: The with_pkg_id field has been removed. After updating, run soar sync to migrate your database.

URL package versioning: The versioning scheme for URL-based packages has changed. If you have URL packages in your packages.toml, run soar apply to update their tracking information. Note that if you didn’t have pkg_id explicitly set, the package may be duplicated since the ID change is treated as a different package. You can remove the old entry manually if this happens.

System-Wide Installs

Until now, Soar only supported per-user installations. This worked well for personal setups, but made it difficult to deploy packages across multi-user systems or manage packages via configuration management tools.

Soar 0.10 adds the -S (or --system) flag for system-wide package management:

soar -S install neovim
soar -S apply
soar -S update

Soar will automatically use sudo or doas for privilege escalation. System packages are installed to /opt/soar, with configuration stored at /etc/soar/config.toml.

GitHub/GitLab as Package Sources

Previously, if a project didn’t have a package in the registry, you had to either wait for someone to add it or manually manage the download URL and version tracking yourself.

Now you can point Soar directly at any GitHub or GitLab repository:

[packages]
neovim = { github = "neovim/neovim", asset_pattern = "*linux-x86_64.appimage" }

Soar will fetch the latest release and select the asset matching your pattern. Version tracking and updates work automatically.

For rate-limited or private repositories, set GITHUB_TOKEN or GITLAB_TOKEN in your environment.

Tag Filtering

Not every release is suitable for production. You can filter releases by tag pattern:

nvim-stable = {
    github = "neovim/neovim",
    asset_pattern = "*linux-x86_64.appimage",
    tag_pattern = "v*.*.*"
}

This ensures you only receive tagged stable releases, ignoring prereleases or nightlies.

Custom Version Detection

For cases where standard release detection doesn’t work (nightly builds, non-standard versioning), you can provide a custom version_command:

nvim-nightly = {
  github = "neovim/neovim",
  asset_pattern = "*linux-x86_64.appimage",
  version_command = "curl -s https://api.gh.pkgforge.dev/repos/neovim/neovim/releases/tags/nightly | jq -r '.published_at, (.assets[] | select(.name | endswith(\"linux-x86_64.appimage\")) | .browser_download_url, .size)'"
}

The command should output up to three newline-separated values: version identifier, download URL, and file size.

Hooks

Some packages need post-install setup: setting permissions, running initialization scripts, or registering with system services. Previously, this had to be done manually after each install or update.

Hooks let you automate these steps:

[packages]
myapp = {
  url = "https://example.com/app.tar.gz",
  hooks = {
    post_extract = "chmod +x bin/*",
    post_install = "./setup.sh",
    pre_remove = "./cleanup.sh"
  }
}

Four hook points are available: post_download, post_extract, post_install, and pre_remove.

Hooks receive several environment variables:

  • INSTALL_DIR: the package installation directory
  • BIN_DIR: Soar’s bin directory
  • PKG_NAME, PKG_ID, PKG_VERSION: package metadata

Build From Source

Not everything ships prebuilt binaries. Some projects only distribute source tarballs, or you may need custom compile flags for your environment.

Soar can now build packages from source:

[packages]
lua = {
  url = "https://www.lua.org/ftp/lua-5.4.7.tar.gz",
  extract_root = "lua-5.4.7",
  build = {
    commands = [
      "make linux -j$NPROC",
      "make install INSTALL_TOP=$INSTALL_DIR"
    ],
    dependencies = ["gcc", "make", "libreadline-dev"]
  },
  binaries = [
    { source = "bin/lua", link_as = "lua" },
    { source = "bin/luac", link_as = "luac" }
  ]
}

The $NPROC environment variable is set to your CPU core count for parallel compilation. The dependencies field documents build requirements; Soar doesn’t install these automatically.

Landlock Sandboxing

Running arbitrary build scripts and hooks from the internet is inherently risky. A malicious or buggy script could read sensitive files or modify system state.

Soar 0.10 integrates Linux’s Landlock LSM to sandbox hook and build command execution:

[packages]
untrusted-pkg = {
  url = "https://example.com/pkg.tar.gz",
  sandbox = {
    require = true,
    fs_read = ["/opt/libs"],
    fs_write = ["/var/tmp"]
  },
  hooks = {
    post_extract = "make build"
  }
}

By default, sandboxed commands can:

  • Read: /usr, /lib, /bin, /etc/ssl/certs, /proc, /sys, and other standard system paths
  • Write: the package’s install directory and /tmp

Additional paths can be granted via fs_read and fs_write.

Setting require = true makes Soar fail if Landlock is unavailable (older kernels or disabled). With require = false, Soar warns and proceeds unsandboxed.

Soar’s automatic binary discovery works well for simple packages, but sometimes you need more control: renaming binaries, creating multiple symlinks to the same executable, or selecting specific binaries from a package.

The entrypoint field handles simple renaming:

app = {
  url = "https://example.com/app.tar.gz",
  entrypoint = "bin/actual-binary-name"
}

For multiple symlinks, use binaries:

neovim = {
  github = "neovim/neovim",
  asset_pattern = "*.appimage",
  binaries = [
    { source = "neovim", link_as = "nvim" },
    { source = "neovim", link_as = "vi" }
  ]
}

Note: Downloaded assets are renamed to match the package name, hence the source being neovim rather than the original filename.

GHCR Support

GitHub Container Registry images can now be used as package sources:

[packages]
tool = { url = "ghcr.io/owner/repo:v1.0.0", entrypoint = "app" }

Or install directly from the command line:

soar install ghcr.io/pkgforge/tool:latest

Full Example

Here’s a packages.toml demonstrating the new features together:

[packages]
# Registry package
curl = "*"

# GitHub release with asset pattern
ripgrep = { github = "BurntSushi/ripgrep", asset_pattern = "*x86_64*linux-musl*.gz" }

# Full build configuration
my-tool = {
  url = "https://example.com/tool-2.0.0.tar.gz",
  version = "2.0.0",
  extract_root = "tool-2.0.0",

  build = {
    commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"],
    dependencies = ["gcc", "make"]
  },

  hooks = { post_install = "$INSTALL_DIR/bin/tool --setup" },

  sandbox = { require = false, fs_read = ["/usr/include"] },

  binaries = [
    { source = "bin/tool", link_as = "tool" },
    { source = "bin/toolctl", link_as = "toolctl" }
  ]
}

What Else?

  • soar update now properly tracks and updates URL-based and GitHub/GitLab packages when managed declaratively via packages.toml. Packages installed directly with soar install don’t support updates for these sources, as there’s not enough context to determine how to fetch newer versions