# Installing `tess`
Supported platforms: **macOS** and **Linux**. Windows is not currently
supported (the stdin / `/dev/tty` plumbing is Unix-specific).
There are three install routes, in order of convenience:
1. **Homebrew tap** — one command, builds from source under the hood.
2. **`cargo install`** from crates.io — needs a Rust toolchain, no tarball
handling.
3. **Source tarball** — full manual flow; documented below.
---
## Homebrew tap
```sh
brew install codedeviate/cli/tess
```
The formula lives in the [`codedeviate/homebrew-cli`](https://github.com/codedeviate/homebrew-cli)
tap (`brew tap codedeviate/cli` if you want the explicit two-step). Source-build
formula — first install compiles `tess` and pulls in `rust` as a build
dependency. To track `master` instead of the latest tagged release, add `--HEAD`.
To upgrade later:
```sh
brew update && brew upgrade tess
```
---
## crates.io
```sh
cargo install tess-cli
```
The crate is published as **`tess-cli`** (the bare `tess` name on crates.io is
an unrelated parked crate). The installed binary is still `tess`, in
`~/.cargo/bin/tess` — make sure that's on `$PATH`. Same Rust prerequisite as
the source build below.
To upgrade: `cargo install --force tess-cli` (or `cargo install-update -a` if
you use [`cargo-update`](https://github.com/nabijaczleweli/cargo-update)).
---
## From source
The rest of this document covers the manual source-tarball flow. The resulting
binary is a single static-ish executable you can drop anywhere on `$PATH`.
### 1. Prerequisites
- **Rust 1.85 or newer** (transitive dep `clap_lex` requires edition 2024). Install via
[rustup](https://rustup.rs):
```sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
Then make sure `~/.cargo/bin` is on your `$PATH` (rustup's installer
prints the snippet to add to your shell rc).
- A C linker (already present on macOS via Xcode CLI tools; on Debian/Ubuntu
install `build-essential`, on Fedora `gcc`).
Verify:
```sh
rustc --version # rustc 1.85.0 or newer
cargo --version
```
---
### 2. Unpack
```sh
tar -xzf tess-<version>.tar.gz
cd tess-<version> # or wherever the archive extracted to
```
The archive contains everything needed to build offline once dependencies are
fetched: `Cargo.toml`, `Cargo.lock`, `src/`, `tests/`, `MANUAL.md`, and this
file.
> **Note:** the archive does not have a top-level `tess-<version>/` directory —
> it extracts straight into the current working directory. Run `tar` from a
> fresh directory if you don't want files mixed with existing ones:
>
> ```sh
> mkdir tess-<version> && cd tess-<version>
> tar -xzf ../tess-<version>.tar.gz
> ```
---
### 3. Build
Release build (optimised, what you want for daily use):
```sh
cargo build --release
```
The binary lands at `target/release/tess`. First build downloads dependencies
and takes 30-60 seconds; subsequent builds are incremental.
Run the test suite to confirm everything is healthy:
```sh
cargo test
```
You should see all tests pass (~140 across unit, integration, and doc tests).
---
### 4. Install
Pick wherever your `$PATH` points. Common choices:
```sh
# Per-user, no sudo needed (recommended):
mkdir -p ~/.local/bin
install -m 755 target/release/tess ~/.local/bin/tess
# Or system-wide:
sudo install -m 755 target/release/tess /usr/local/bin/tess
```
> **Why `install` instead of `cp`?** On macOS 14+ (and especially 26 /
> Tahoe), the kernel may attach a `com.apple.provenance` extended attribute
> to binaries copied into protected locations like `/usr/local/bin`. If
> XProtect doesn't recognise the provenance, the kernel SIGKILLs the
> process on exec and you'll see `zsh: killed tess` with no further
> diagnostic. `install` avoids attaching the attribute.
>
> **If you already used `cp` and hit this**, both steps below are required
> on macOS 26 — stripping the xattr alone isn't enough because the kernel
> caches a "suspicious" verdict; re-signing produces a fresh `cdhash` that
> gets re-evaluated:
>
> ```sh
> sudo xattr -c /usr/local/bin/tess
> sudo codesign --force --sign - /usr/local/bin/tess
> tess --version # should print 'tess <version>'
> ```
Make sure your chosen directory is on `$PATH`. For `~/.local/bin`, add this to
`~/.zshrc` or `~/.bashrc` if it's not already:
```sh
export PATH="$HOME/.local/bin:$PATH"
```
Verify:
```sh
which tess
tess --version # tess <version>
```
---
## First run
```sh
tess --help # flag list (alphabetical by long name)
tess --examples # curated usage recipes
tess --manual # the full manual, paged through tess itself
tess Cargo.toml # open a file
`tess --manual` and `tess --examples` open inside the pager when stdout is a
terminal, and print plain text when piped (`tess --manual | grep foo`,
`tess --manual > MANUAL.txt`).
---
## Optional: user config
`tess` reads optional log formats and command-line groups from
`~/.config/tess/formats.toml`. See the **Log formats** and **Groups** sections
of `MANUAL.md` (or run `tess --manual`) for the schema. The file is optional —
the built-in formats (`apache-common`, `apache-combined`, `nginx-combined`)
work without any config.
---
## Updating
| Homebrew | `brew update && brew upgrade tess` |
| crates.io | `cargo install --force tess-cli` |
| Source tarball | Re-run unpack → build → install with the newer tarball. `cargo build --release` reuses cached dependencies, so updates are quick. |
---
## Uninstall
| Homebrew | `brew uninstall tess` (and `brew untap codedeviate/cli` to drop the tap entirely) |
| crates.io | `cargo uninstall tess-cli` |
| Source tarball | `rm -f ~/.local/bin/tess` (or wherever you put it) |
Drop user config separately if you want a fully clean removal:
```sh
rm -rf ~/.config/tess
```